diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index fcfac85ed9c442..fe10e45b679226 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -42,7 +42,7 @@ jobs: testRunPlatform: macos pool: - vmImage: xcode9-macos10.13 + vmImage: macos-10.14 steps: - template: ./macos-steps.yml @@ -59,7 +59,7 @@ jobs: variables: testRunTitle: '$(build.sourceBranchName)-linux' testRunPlatform: linux - openssl_version: 1.1.1c + openssl_version: 1.1.1d steps: - template: ./posix-steps.yml @@ -116,7 +116,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1c + openssl_version: 1.1.1d steps: - template: ./posix-steps.yml @@ -131,7 +131,7 @@ jobs: condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) pool: - vmImage: vs2017-win2016 + vmImage: windows-2019 strategy: matrix: diff --git a/.azure-pipelines/macos-steps.yml b/.azure-pipelines/macos-steps.yml index 647081689454ac..d2ca580a93d7dd 100644 --- a/.azure-pipelines/macos-steps.yml +++ b/.azure-pipelines/macos-steps.yml @@ -14,6 +14,8 @@ steps: - script: make buildbottest TESTOPTS="-j4 -uall,-cpu --junit-xml=$(build.binariesDirectory)/test-results.xml" displayName: 'Tests' + continueOnError: true + timeoutInMinutes: 30 - task: PublishTestResults@2 displayName: 'Publish Test Results' diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index 2486f88a63fb15..09209fc0c954d0 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -40,7 +40,7 @@ jobs: testRunPlatform: macos pool: - vmImage: xcode9-macos10.13 + vmImage: macos-10.14 steps: - template: ./macos-steps.yml @@ -59,7 +59,7 @@ jobs: variables: testRunTitle: '$(system.pullRequest.TargetBranch)-linux' testRunPlatform: linux - openssl_version: 1.1.1c + openssl_version: 1.1.1d steps: - template: ./posix-steps.yml @@ -116,7 +116,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1c + openssl_version: 1.1.1d steps: - template: ./posix-steps.yml @@ -131,7 +131,7 @@ jobs: condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) pool: - vmImage: vs2017-win2016 + vmImage: windows-2019 strategy: matrix: diff --git a/.azure-pipelines/windows-release.yml b/.azure-pipelines/windows-release.yml new file mode 100644 index 00000000000000..3d072e3b43e17e --- /dev/null +++ b/.azure-pipelines/windows-release.yml @@ -0,0 +1,129 @@ +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 new file mode 100644 index 00000000000000..d4563cd0d722c1 --- /dev/null +++ b/.azure-pipelines/windows-release/build-steps.yml @@ -0,0 +1,83 @@ +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 + .\python.bat PC\layout -vv -t "$(Build.BinariesDirectory)\catalog" --catalog "${env:CAT}.cdf" --preset-default + 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 + +- 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 new file mode 100644 index 00000000000000..d42d55fff08dda --- /dev/null +++ b/.azure-pipelines/windows-release/checkout.yml @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000000000..e4de78555b3f66 --- /dev/null +++ b/.azure-pipelines/windows-release/find-sdk.yml @@ -0,0 +1,17 @@ +# 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 new file mode 100644 index 00000000000000..0855af8d703df9 --- /dev/null +++ b/.azure-pipelines/windows-release/gpg-sign.yml @@ -0,0 +1,28 @@ +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 new file mode 100644 index 00000000000000..2dcd6ed26ca3a8 --- /dev/null +++ b/.azure-pipelines/windows-release/layout-command.yml @@ -0,0 +1,15 @@ +steps: +- powershell: > + Write-Host ( + '##vso[task.setvariable variable=LayoutCmd]& + "{0}\bin\python.exe" + "{1}\PC\layout" + -vv + --source "{1}" + --build "{0}\bin" + --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 new file mode 100644 index 00000000000000..30f7d34fa61d23 --- /dev/null +++ b/.azure-pipelines/windows-release/mingw-lib.yml @@ -0,0 +1,13 @@ +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 new file mode 100644 index 00000000000000..f7bff162f8e027 --- /dev/null +++ b/.azure-pipelines/windows-release/msi-steps.yml @@ -0,0 +1,128 @@ +steps: + - template: ./checkout.yml + + - 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' + + - 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 new file mode 100644 index 00000000000000..c98576ef9705c0 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-build.yml @@ -0,0 +1,160 @@ +jobs: +- job: Build_Docs + displayName: Docs build + pool: + name: 'Windows Release' + #vmName: win2016-vs2017 + + workspace: + clean: all + + steps: + - template: ./checkout.yml + + - script: Doc\make.bat html + displayName: 'Build HTML docs' + env: + BUILDDIR: $(Build.BinariesDirectory)\Doc + + #- powershell: iwr "https://www.python.org/ftp/python/3.7.3/python373.chm" -OutFile "$(Build.BinariesDirectory)\python390a0.chm" + # displayName: 'Cheat at building CHM docs' + + - script: Doc\make.bat htmlhelp + displayName: 'Build CHM docs' + env: + BUILDDIR: $(Build.BinariesDirectory)\Doc + + - 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: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + win32: + Name: win32 + Arch: win32 + Platform: x86 + Configuration: Release + win32_d: + Name: win32_d + Arch: win32 + Platform: x86 + Configuration: Debug + amd64_d: + Name: amd64_d + Arch: amd64 + Platform: x64 + Configuration: Debug + + steps: + - template: ./build-steps.yml + +- job: Build_Python_NonPGO + displayName: Python non-PGO build + condition: and(succeeded(), ne(variables['DoPGO'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + amd64: + Name: amd64 + Arch: amd64 + Platform: x64 + Configuration: Release + + 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 + + steps: + - template: ./build-steps.yml + parameters: + ShouldPGO: true + + +- job: TclTk_Lib + displayName: Publish Tcl/Tk Library + + pool: + vmName: windows-latest + + 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 new file mode 100644 index 00000000000000..09857ff676b355 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-layout-embed.yml @@ -0,0 +1,56 @@ +jobs: +- job: Make_Embed_Layout + displayName: Make embeddable layout + condition: and(succeeded(), eq(variables['DoEmbed'], 'true')) + + pool: + vmName: win2016-vs2017 + + 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) + + 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 new file mode 100644 index 00000000000000..12c347239013c1 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-layout-full.yml @@ -0,0 +1,66 @@ +jobs: +- job: Make_Layouts + displayName: Make layouts + condition: and(succeeded(), eq(variables['DoLayout'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + win32: + Name: win32 + Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + amd64: + Name: amd64 + Python: $(Build.BinariesDirectory)\bin_$(Name)\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)' + 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' + + - template: ./layout-command.yml + + - powershell: | + $(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\layout" --preset-default + displayName: 'Generate full layout' + env: + TCL_LIBRARY: $(Build.BinariesDirectory)\tcltk_lib\tcl8 + + - 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 new file mode 100644 index 00000000000000..ba86392f3ec699 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-layout-msix.yml @@ -0,0 +1,88 @@ +jobs: +- job: Make_MSIX_Layout + displayName: Make MSIX layout + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + #win32: + # Name: win32 + # Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + # PYTHONHOME: $(Build.SourcesDirectory) + amd64: + Name: amd64 + Python: $(Build.BinariesDirectory)\bin_$(Name)\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)' + 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' + + - 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: $(Build.BinariesDirectory)\tcltk_lib\tcl8 + + - 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: $(Build.BinariesDirectory)\tcltk_lib\tcl8 + + - 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 new file mode 100644 index 00000000000000..7954c4547f50ab --- /dev/null +++ b/.azure-pipelines/windows-release/stage-layout-nuget.yml @@ -0,0 +1,48 @@ +jobs: +- job: Make_Nuget_Layout + displayName: Make Nuget layout + condition: and(succeeded(), eq(variables['DoNuget'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + win32: + Name: win32 + Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + amd64: + Name: amd64 + Python: $(Build.BinariesDirectory)\bin_$(Name)\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' + + - template: ./layout-command.yml + + - powershell: | + $(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\nuget" --preset-nuget + displayName: 'Generate nuget layout' + env: + TCL_LIBRARY: $(Build.BinariesDirectory)\bin_$(Name)\tcl\tcl8 + + - 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 new file mode 100644 index 00000000000000..7afc816a0c6e9c --- /dev/null +++ b/.azure-pipelines/windows-release/stage-msi.yml @@ -0,0 +1,36 @@ +jobs: +- job: Make_MSI + displayName: Make MSI + condition: and(succeeded(), not(variables['SigningCertificate'])) + + pool: + vmName: win2016-vs2017 + + 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 new file mode 100644 index 00000000000000..eebc63fb8809bc --- /dev/null +++ b/.azure-pipelines/windows-release/stage-pack-msix.yml @@ -0,0 +1,127 @@ +jobs: +- job: Pack_MSIX + displayName: Pack MSIX bundles + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + amd64: + Name: amd64 + Artifact: appx + Suffix: + ShouldSign: true + amd64_store: + Name: amd64 + 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: + - checkout: none + - template: ./find-sdk.yml + + - task: DownloadBuildArtifacts@0 + displayName: 'Download Artifact: unsigned_msix' + inputs: + artifactName: unsigned_msix + downloadPath: $(Build.BinariesDirectory) + + - powershell: | + $failed = $true + foreach ($retry in 1..3) { + signtool sign /a /n "$(SigningCertificate)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /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 new file mode 100644 index 00000000000000..f59bbe9b39a8d7 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-pack-nuget.yml @@ -0,0 +1,41 @@ +jobs: +- job: Pack_Nuget + displayName: Pack Nuget bundles + condition: and(succeeded(), eq(variables['DoNuget'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + amd64: + Name: amd64 + win32: + Name: win32 + + 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' + + - 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 new file mode 100644 index 00000000000000..570cdb3ec57f0d --- /dev/null +++ b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml @@ -0,0 +1,41 @@ +jobs: +- job: Publish_Nuget + displayName: Publish Nuget packages + condition: and(succeeded(), eq(variables['DoNuget'], 'true')) + + pool: + vmName: win2016-vs2017 + + 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) + + - 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 new file mode 100644 index 00000000000000..2dd354a8c276f6 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml @@ -0,0 +1,154 @@ +jobs: +- job: Publish_Python + displayName: Publish python.org packages + condition: and(succeeded(), and(eq(variables['DoMSI'], 'true'), eq(variables['DoEmbed'], 'true'))) + + pool: + #vmName: win2016-vs2017 + 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) + + + - 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 new file mode 100644 index 00000000000000..b22147b1ab45e7 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-publish-store.yml @@ -0,0 +1,35 @@ +jobs: +- job: Publish_Store + displayName: Publish Store packages + condition: and(succeeded(), eq(variables['DoMSIX'], 'true')) + + pool: + vmName: win2016-vs2017 + + 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 new file mode 100644 index 00000000000000..2307c6c9c8f97d --- /dev/null +++ b/.azure-pipelines/windows-release/stage-sign.yml @@ -0,0 +1,122 @@ +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 + + steps: + - template: ./checkout.yml + - template: ./find-sdk.yml + + - 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 /t http://timestamp.verisign.com/scripts/timestamp.dll $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: + vmName: win2016-vs2017 + + 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 new file mode 100644 index 00000000000000..b33176266a20da --- /dev/null +++ b/.azure-pipelines/windows-release/stage-test-embed.yml @@ -0,0 +1,41 @@ +jobs: +- job: Test_Embed + displayName: Test Embed + condition: and(succeeded(), eq(variables['DoEmbed'], 'true')) + + pool: + vmName: win2016-vs2017 + + 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 new file mode 100644 index 00000000000000..27b0c96987a7a0 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-test-msi.yml @@ -0,0 +1,108 @@ +jobs: +- job: Test_MSI + displayName: Test MSI + + pool: + vmName: win2016-vs2017 + + 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 new file mode 100644 index 00000000000000..1f8b601d0d023b --- /dev/null +++ b/.azure-pipelines/windows-release/stage-test-nuget.yml @@ -0,0 +1,58 @@ +jobs: +- job: Test_Nuget + displayName: Test Nuget + condition: and(succeeded(), eq(variables['DoNuget'], 'true')) + + pool: + vmName: win2016-vs2017 + + 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 c9a54fbd472ecc..bec16a08152ebb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -54,7 +54,7 @@ Python/Python-ast.c linguist-generated=true Include/opcode.h linguist-generated=true Python/opcode_targets.h linguist-generated=true Objects/typeslots.inc linguist-generated=true -Modules/unicodedata_db.h linguist-generated=true +*_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 diff --git a/.github/appveyor.yml b/.github/appveyor.yml deleted file mode 100644 index e8012f69ee5b2e..00000000000000 --- a/.github/appveyor.yml +++ /dev/null @@ -1,38 +0,0 @@ -version: 3.8build{build} -clone_depth: 5 -branches: - only: - - master - - /\d\.\d/ - - buildbot-custom -cache: - - externals -> PCbuild -before_build: - - ps: |+ - if ($env:APPVEYOR_RE_BUILD) { - echo 'Doing full build due to re-build request.' - } elseif (!$env:APPVEYOR_PULL_REQUEST_HEAD_COMMIT) { - echo 'Not a PR, doing full build.' - } else { - git fetch -q origin +refs/heads/$env:APPVEYOR_REPO_BRANCH - $mergebase = git merge-base HEAD FETCH_HEAD - $changes = git diff --name-only HEAD $mergebase | grep -vE '(\.rst$)|(^Doc)|(^Misc)' - If (!$changes) { - echo 'Only docs were updated, stopping build process.' - Exit-AppveyorBuild - } else { - echo 'Doing full build due to non-doc changes in these files:' - echo $changes - } - } - - -build_script: - - cmd: PCbuild\build.bat -e -p x64 - - cmd: PCbuild\amd64\python.exe -m test.pythoninfo -test_script: - - cmd: PCbuild\rt.bat -x64 -q -uall -u-cpu -u-largefile -rwW --slowest --timeout=1200 --fail-env-changed -j0 -environment: - HOST_PYTHON: C:\Python36\python.exe -image: - - Visual Studio 2017 diff --git a/.gitignore b/.gitignore index 9445ef1e2c5252..b662374b1255cb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,14 @@ -# added for local development -.buildaix/ -Modules/python.exp -buildaix/ -installp/ -.gitignore +##### +# First, rules intended to apply in all subdirectories. +# These contain no slash, or only a trailing slash. -# Two-trick pony for OSX and other case insensitive file systems: -# Ignore ./python binary on Unix but still look into ./Python/ directory. -/python -!/Python/ *.cover *.iml *.o +*.a +*.so* +*.dylib +*.dll *.orig *.pyc *.pyd @@ -24,6 +21,31 @@ installp/ *.profraw *.dyn .gdb_history +.purify +__pycache__ +.hg/ +.svn/ +.idea/ +tags +TAGS +.vs/ +.vscode/ +gmon.out +.coverage +.mypy_cache/ + +*.exe +!Lib/distutils/command/*.exe + +# Ignore core dumps... but not Tools/msi/core/ or the like. +core +!core/ + + +##### +# Then, rules meant for a specific location relative to the repo root. +# These must contain a non-trailing slash (and may also have a trailing slash.) + Doc/build/ Doc/venv/ Doc/.venv/ @@ -33,23 +55,20 @@ Include/pydtrace_probes.h Lib/distutils/command/*.pdb Lib/lib2to3/*.pickle Lib/test/data/* -Makefile -Makefile.pre +!Lib/test/data/README +/Makefile +/Makefile.pre Misc/python.pc Misc/python-embed.pc Misc/python-config.sh -Modules/Setup Modules/Setup.config Modules/Setup.local Modules/config.c Modules/ld_so_aix Programs/_freeze_importlib -Programs/_freeze_importlib.exe Programs/_testembed -Programs/_testembed.exe PC/python_nt*.h PC/pythonnt_rc*.h -PC/*/*.exe PC/*/*.exp PC/*/*.lib PC/*/*.bsc @@ -68,51 +87,34 @@ PCbuild/*-pgi PCbuild/*-pgo PCbuild/*.VC.db PCbuild/*.VC.opendb -PCbuild/.vs/ PCbuild/amd64/ PCbuild/arm32/ PCbuild/arm64/ PCbuild/obj/ PCbuild/win32/ -.purify -__pycache__ -autom4te.cache -build/ -buildno -config.cache -config.log -config.status -config.status.lineno -core -db_home -.hg/ -.idea/ -ipch/ -libpython*.a -libpython*.so* -libpython*.dylib -libpython*.dll -platform -pybuilddir.txt -pyconfig.h -python-config -python-config.py -python.bat -python.exe -python-gdb.py -python.exe-gdb.py -reflog.txt -.svn/ -tags -TAGS -.coverage -coverage/ -externals/ -htmlcov/ +/autom4te.cache +/build/ +/config.cache +/config.log +/config.status +/config.status.lineno +/platform +/pybuilddir.txt +/pyconfig.h +/python-config +/python-config.py +/python.bat +/python-gdb.py +/python.exe-gdb.py +/reflog.txt +/coverage/ +/externals/ +/htmlcov/ Tools/msi/obj Tools/ssl/amd64 Tools/ssl/win32 -.vs/ -.vscode/ -gmon.out -.mypy_cache/ + +# Two-trick pony for OSX and other case insensitive file systems: +# Ignore ./python binary on Unix but still look into ./Python/ directory. +/python +!/Python/ diff --git a/.travis.yml b/.travis.yml index 02de997750abc8..8a960c53426f59 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,11 +11,10 @@ cache: env: global: - - OPENSSL=1.1.1c + - OPENSSL=1.1.1d - OPENSSL_DIR="$HOME/multissl/openssl/${OPENSSL}" - PATH="${OPENSSL_DIR}/bin:$PATH" - # Use -O3 because we don't use debugger on Travis-CI - - CFLAGS="-I${OPENSSL_DIR}/include -O3" + - 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 @@ -43,6 +42,7 @@ matrix: addons: apt: packages: + - gdb - xvfb - name: "Documentation build" os: linux @@ -73,16 +73,6 @@ matrix: - make -C Doc/ PYTHON=../python venv script: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W -j4" doctest - - name: "Mac OS X tests" - os: osx - language: c - compiler: clang - # Testing under macOS is optional until testing stability has been demonstrated. - env: OPTIONAL=true - before_install: - # Python 3 is needed for Argument Clinic and multissl - - HOMEBREW_NO_AUTO_UPDATE=1 brew install xz python3 - - export PATH=$(brew --prefix)/bin:$(brew --prefix)/sbin:$PATH - name: "Test code coverage (Python)" os: linux language: c @@ -166,7 +156,8 @@ install: # Travis provides only 2 cores, so don't overdo the parallelism and waste memory. before_script: - - ./configure --with-pydebug + # -Og is much faster than -O0 + - CFLAGS="${CFLAGS} -Og" ./configure --with-pydebug - make -j4 regen-all - changes=`git status --porcelain` - | diff --git a/Doc/Makefile b/Doc/Makefile index 6f86728ea834c3..f589b6e75f6180 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -13,10 +13,14 @@ SOURCES = DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py) SPHINXERRORHANDLING = -W -ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees -D latex_elements.papersize=$(PAPER) \ +# Internal variables. +PAPEROPT_a4 = -D latex_elements.papersize=a4paper +PAPEROPT_letter = -D latex_elements.papersize=letterpaper + +ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(PAPEROPT_$(PAPER)) \ $(SPHINXOPTS) $(SPHINXERRORHANDLING) . build/$(BUILDER) $(SOURCES) -.PHONY: help build html htmlhelp latex text changes linkcheck \ +.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 @@ -29,6 +33,7 @@ help: @echo " htmlhelp to make HTML files and a HTML help project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " text to make plain text files" + @echo " texinfo to make Texinfo file" @echo " epub to make EPUB files" @echo " changes to make an overview over all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @@ -85,6 +90,11 @@ text: BUILDER = text text: build @echo "Build finished; the text files are in build/text." +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." + epub: BUILDER = epub epub: build @echo "Build finished; the epub files are in build/epub." @@ -179,6 +189,17 @@ dist: make epub cp -pPR build/epub/Python.epub dist/python-$(DISTVERSION)-docs.epub + # archive the texinfo build + rm -rf build/texinfo + make texinfo + make info --directory=build/texinfo + cp -pPR build/texinfo dist/python-$(DISTVERSION)-docs-texinfo + tar -C dist -cf dist/python-$(DISTVERSION)-docs-texinfo.tar python-$(DISTVERSION)-docs-texinfo + bzip2 -9 -k dist/python-$(DISTVERSION)-docs-texinfo.tar + (cd dist; zip -q -r -9 python-$(DISTVERSION)-docs-texinfo.zip python-$(DISTVERSION)-docs-texinfo) + rm -r dist/python-$(DISTVERSION)-docs-texinfo + rm dist/python-$(DISTVERSION)-docs-texinfo.tar + check: $(PYTHON) tools/rstlint.py -i tools -i $(VENVDIR) -i README.rst diff --git a/Doc/bugs.rst b/Doc/bugs.rst index 1e044ad2033d87..a17f04d26fa40b 100644 --- a/Doc/bugs.rst +++ b/Doc/bugs.rst @@ -80,7 +80,7 @@ taken on the bug. Article which goes into some detail about how to create a useful bug report. This describes what kind of information is useful and why it is useful. - `Bug Writing Guidelines `_ + `Bug Report Writing Guidelines `_ Information about writing a good bug report. Some of this is specific to the Mozilla project, but describes general good practices. diff --git a/Doc/c-api/allocation.rst b/Doc/c-api/allocation.rst index 8e8a92003c5a3e..33b0c06a9ebc2e 100644 --- a/Doc/c-api/allocation.rst +++ b/Doc/c-api/allocation.rst @@ -48,7 +48,7 @@ Allocating Objects on the Heap improving the memory management efficiency. -.. c:function:: void PyObject_Del(PyObject *op) +.. c:function:: void PyObject_Del(void *op) Releases memory allocated to an object using :c:func:`PyObject_New` or :c:func:`PyObject_NewVar`. This is normally called from the diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst index 72d965053cfda3..67140511ef74f4 100644 --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -355,8 +355,10 @@ If :c:member:`~Py_buffer.strides` is *NULL*, the array is interpreted as a standard n-dimensional C-array. Otherwise, the consumer must access an n-dimensional array as follows: - ``ptr = (char *)buf + indices[0] * strides[0] + ... + indices[n-1] * strides[n-1]`` - ``item = *((typeof(item) *)ptr);`` +.. code-block:: c + + ptr = (char *)buf + indices[0] * strides[0] + ... + indices[n-1] * strides[n-1]; + item = *((typeof(item) *)ptr); As noted above, :c:member:`~Py_buffer.buf` can point to any location within @@ -473,11 +475,24 @@ Buffer-related functions (*order* is ``'A'``). Return ``0`` otherwise. This function always succeeds. +.. c:function:: void* PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices) + + Get the memory area pointed to by the *indices* inside the given *view*. + *indices* must point to an array of ``view->ndim`` indices. + + +.. c:function:: int PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort) + + Copy contiguous *len* bytes from *buf* to *view*. + *fort* can be ``'C'`` or ``'F'`` (for C-style or Fortran-style ordering). + ``0`` is returned on success, ``-1`` on error. + + .. c:function:: int PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order) Copy *len* bytes from *src* to its contiguous representation in *buf*. - *order* can be ``'C'`` or ``'F'`` (for C-style or Fortran-style ordering). - ``0`` is returned on success, ``-1`` on error. + *order* can be ``'C'`` or ``'F'`` or ``'A'`` (for C-style or Fortran-style + ordering or either one). ``0`` is returned on success, ``-1`` on error. This function fails if *len* != *src->len*. diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 48428109e6f2fe..45a6b4a753a729 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -33,19 +33,18 @@ bound into a function. Return the number of free variables in *co*. -.. c:function:: PyCodeObject* PyCode_New(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) +.. 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) - 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. + 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. - .. versionchanged:: 3.8 - An extra parameter is required (*posonlyargcount*) to support :PEP:`570`. - The first parameter (*argcount*) now represents the total number of positional arguments, - including positional-only. +.. 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) - .. audit-event:: code.__new__ "code filename name argcount posonlyargcount kwonlyargcount nlocals stacksize flags" + Similar to :c:func:`PyCode_New`, but with an extra "posonlyargcount" for positonal-only arguments. + + .. versionadded:: 3.8 .. c:function:: PyCodeObject* PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index d3f6daa8347e41..25bb657dca0e16 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -320,7 +320,7 @@ an error value). :mod:`warnings` module and the :option:`-W` option in the command line documentation. There is no C API for warning control. -.. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *msg, PyObject *name, PyObject *path) +.. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path) Much like :c:func:`PyErr_SetImportError` but this function allows for specifying a subclass of :exc:`ImportError` to raise. @@ -809,7 +809,6 @@ the variables: single: PyExc_SystemError single: PyExc_SystemExit single: PyExc_TabError - single: PyExc_TargetScopeError single: PyExc_TimeoutError single: PyExc_TypeError single: PyExc_UnboundLocalError @@ -911,8 +910,6 @@ the variables: +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_TabError` | :exc:`TabError` | | +-----------------------------------------+---------------------------------+----------+ -| :c:data:`PyExc_TargetScopeError` | :exc:`TargetScopeError` | | -+-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_TimeoutError` | :exc:`TimeoutError` | | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_TypeError` | :exc:`TypeError` | | diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index a0ac4d21d13936..0b7a84d031532e 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -7,6 +7,8 @@ Initialization, Finalization, and Threads ***************************************** +See also :ref:`Python Initialization Configuration `. + .. _pre-init-safe: Before Python Initialization @@ -299,8 +301,9 @@ Initializing and finalizing the interpreter than once; this can happen if an application calls :c:func:`Py_Initialize` and :c:func:`Py_FinalizeEx` more than once. - .. versionadded:: 3.6 + .. audit-event:: cpython._PySys_ClearAuditHooks "" c.Py_FinalizeEx + .. versionadded:: 3.6 .. c:function:: void Py_Finalize() @@ -469,8 +472,8 @@ Process-wide parameters dependent delimiter character, which is ``':'`` on Unix and Mac OS X, ``';'`` on Windows. - This also causes :data:`sys.executable` to be set only to the raw program - name (see :c:func:`Py_SetProgramName`) and for :data:`sys.prefix` and + This also causes :data:`sys.executable` to be set to the program + full path (see :c:func:`Py_GetProgramFullPath`) and for :data:`sys.prefix` and :data:`sys.exec_prefix` to be empty. It is up to the caller to modify these if required after calling :c:func:`Py_Initialize`. @@ -480,6 +483,10 @@ Process-wide parameters The path argument is copied internally, so the caller may free it after the call completes. + .. versionchanged:: 3.8 + The program full path is now used for :data:`sys.executable`, instead + of the program name. + .. c:function:: const char* Py_GetVersion() @@ -990,12 +997,16 @@ All of the following functions must be called after :c:func:`Py_Initialize`. be held, but may be held if it is necessary to serialize calls to this function. + .. audit-event:: cpython.PyInterpreterState_New "" c.PyInterpreterState_New + .. c:function:: void PyInterpreterState_Clear(PyInterpreterState *interp) Reset all information in an interpreter state object. The global interpreter lock must be held. + .. audit-event:: cpython.PyInterpreterState_Clear "" c.PyInterpreterState_Clear + .. c:function:: void PyInterpreterState_Delete(PyInterpreterState *interp) @@ -1141,10 +1152,18 @@ Sub-interpreter support While in most uses, you will only embed a single Python interpreter, there are cases where you need to create several independent interpreters in the -same process and perhaps even in the same thread. Sub-interpreters allow -you to do that. You can switch between sub-interpreters using the -:c:func:`PyThreadState_Swap` function. You can create and destroy them -using the following functions: +same process and perhaps even in the same thread. Sub-interpreters allow +you to do that. + +The "main" interpreter is the first one created when the runtime initializes. +It is usually the only Python interpreter in a process. Unlike sub-interpreters, +the main interpreter has unique process-global responsibilities like signal +handling. It is also responsible for execution during runtime initialization and +is usually the active interpreter during runtime finalization. The +:c:func:`PyInterpreterState_Main` funtion returns a pointer to its state. + +You can switch between sub-interpreters using the :c:func:`PyThreadState_Swap` +function. You can create and destroy them using the following functions: .. c:function:: PyThreadState* Py_NewInterpreter() diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index 0d94e6b8f27b57..5e18300471d461 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -25,6 +25,7 @@ Functions: * :c:func:`PyConfig_SetBytesArgv` * :c:func:`PyConfig_SetBytesString` * :c:func:`PyConfig_SetString` +* :c:func:`PyConfig_SetWideStringList` * :c:func:`PyPreConfig_InitIsolatedConfig` * :c:func:`PyPreConfig_InitPythonConfig` * :c:func:`PyStatus_Error` @@ -47,6 +48,8 @@ The preconfiguration (``PyPreConfig`` type) is stored in ``_PyRuntime.preconfig`` and the configuration (``PyConfig`` type) is stored in ``PyInterpreterState.config``. +See also :ref:`Initialization, Finalization, and Threads `. + .. seealso:: :pep:`587` "Python Initialization Configuration". @@ -71,8 +74,12 @@ PyWideStringList .. c:function:: PyStatus PyWideStringList_Insert(PyWideStringList *list, Py_ssize_t index, const wchar_t *item) - Insert *item* into *list* at *index*. If *index* is greater than *list* - length, just append *item* to *list*. + Insert *item* into *list* at *index*. + + If *index* is greater than or equal to *list* length, append *item* to + *list*. + + *index* must be greater than or equal to 0. Python must be preinitialized to call this function. @@ -234,6 +241,7 @@ PyPreConfig locale to decide if it should be coerced. .. c:member:: int coerce_c_locale_warn + If non-zero, emit a warning if the C locale is coerced. .. c:member:: int dev_mode @@ -293,7 +301,7 @@ For :ref:`Python Configuration ` (:c:func:`PyPreConfig_InitPythonConfig`), if Python is initialized with command line arguments, the command line arguments must also be passed to preinitialize Python, since they have an effect on the pre-configuration -like encodings. For example, the :option:`-X` ``utf8`` command line option +like encodings. For example, the :option:`-X utf8 <-X>` command line option enables the UTF-8 Mode. ``PyMem_SetAllocator()`` can be called after :c:func:`Py_PreInitialize` and @@ -308,12 +316,13 @@ the preinitialization. Example using the preinitialization to enable the UTF-8 Mode:: + PyStatus status; PyPreConfig preconfig; PyPreConfig_InitPythonConfig(&preconfig); preconfig.utf8_mode = 1; - PyStatus status = Py_PreInitialize(&preconfig); + status = Py_PreInitialize(&preconfig); if (PyStatus_Exception(status)) { Py_ExitStatusException(status); } @@ -334,12 +343,12 @@ PyConfig Structure methods: - .. c:function:: PyStatus PyConfig_InitPythonConfig(PyConfig *config) + .. c:function:: void PyConfig_InitPythonConfig(PyConfig *config) Initialize configuration with :ref:`Python Configuration `. - .. c:function:: PyStatus PyConfig_InitIsolatedConfig(PyConfig *config) + .. c:function:: void PyConfig_InitIsolatedConfig(PyConfig *config) Initialize configuration with :ref:`Isolated Configuration `. @@ -368,6 +377,12 @@ PyConfig Preinitialize Python if needed. + .. c:function:: PyStatus PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list, Py_ssize_t length, wchar_t **items) + + Set the list of wide strings *list* to *length* and *items*. + + Preinitialize Python if needed. + .. c:function:: PyStatus PyConfig_Read(PyConfig *config) Read all Python configuration. @@ -412,6 +427,11 @@ PyConfig :data:`sys.base_exec_prefix`. + .. c:member:: wchar_t* base_executable + + :data:`sys._base_executable`: ``__PYVENV_LAUNCHER__`` environment + variable value, or copy of :c:member:`PyConfig.executable`. + .. c:member:: wchar_t* base_prefix :data:`sys.base_prefix`. @@ -446,7 +466,7 @@ PyConfig .. c:member:: int dev_mode - Development mode: see :option:`-X` ``dev``. + Development mode: see :option:`-X dev <-X>`. .. c:member:: int dump_refs @@ -464,7 +484,7 @@ PyConfig .. c:member:: int faulthandler - If non-zero, call :func:`faulthandler.enable`. + If non-zero, call :func:`faulthandler.enable` at startup. .. c:member:: wchar_t* filesystem_encoding @@ -486,6 +506,9 @@ PyConfig Python home directory. + Initialized from :envvar:`PYTHONHOME` environment variable value by + default. + .. c:member:: int import_time If non-zero, profile import time. @@ -543,7 +566,7 @@ PyConfig :data:`sys.path`. If :c:member:`~PyConfig.module_search_paths_set` is equal to 0, the :c:member:`~PyConfig.module_search_paths` is overridden - by the function computing the :ref:`Path Configuration + by the function calculating the :ref:`Path Configuration `. .. c:member:: int optimization_level @@ -568,9 +591,9 @@ PyConfig .. c:member:: int pathconfig_warnings - If equal to 0, suppress warnings when computing the path configuration - (Unix only, Windows does not log any warning). Otherwise, warnings are - written into ``stderr``. + If equal to 0, suppress warnings when calculating the :ref:`Path + Configuration ` (Unix only, Windows does not log any + warning). Otherwise, warnings are written into ``stderr``. .. c:member:: wchar_t* prefix @@ -578,39 +601,46 @@ PyConfig .. c:member:: wchar_t* program_name - Program name. + Program name. Used to initialize :c:member:`~PyConfig.executable`, and in + early error messages. .. c:member:: wchar_t* pycache_prefix - ``.pyc`` cache prefix. + :data:`sys.pycache_prefix`: ``.pyc`` cache prefix. + + If NULL, :data:`sys.pycache_prefix` is set to ``None``. .. c:member:: int quiet Quiet mode. For example, don't display the copyright and version messages - even in interactive mode. + in interactive mode. .. c:member:: wchar_t* run_command - ``python3 -c COMMAND`` argument. + ``python3 -c COMMAND`` argument. Used by :c:func:`Py_RunMain`. .. c:member:: wchar_t* run_filename - ``python3 FILENAME`` argument. + ``python3 FILENAME`` argument. Used by :c:func:`Py_RunMain`. .. c:member:: wchar_t* run_module - ``python3 -m MODULE`` argument. + ``python3 -m MODULE`` argument. Used by :c:func:`Py_RunMain`. .. c:member:: int show_alloc_count Show allocation counts at exit? + Set to 1 by :option:`-X showalloccount <-X>` command line option. + Need a special Python build with ``COUNT_ALLOCS`` macro defined. .. c:member:: int show_ref_count Show total reference count at exit? + Set to 1 by :option:`-X showrefcount <-X>` command line option. + Need a debug build of Python (``Py_REF_DEBUG`` macro must be defined). .. c:member:: int site_import @@ -629,7 +659,7 @@ PyConfig .. c:member:: int tracemalloc - If non-zero, call :func:`tracemalloc.start`. + If non-zero, call :func:`tracemalloc.start` at startup. .. c:member:: int use_environment @@ -645,12 +675,21 @@ PyConfig .. c:member:: PyWideStringList warnoptions - Options of the :mod:`warnings` module to build warnings filters. + :data:`sys.warnoptions`: options of the :mod:`warnings` module to build + warnings filters: lowest to highest priority. + + The :mod:`warnings` module adds :data:`sys.warnoptions` in the reverse + order: the last :c:member:`PyConfig.warnoptions` item becomes the first + item of :data:`warnings.filters` which is checked first (highest + priority). .. c:member:: int write_bytecode If non-zero, write ``.pyc`` files. + :data:`sys.dont_write_bytecode` is initialized to the inverted value of + :c:member:`~PyConfig.write_bytecode`. + .. c:member:: PyWideStringList xoptions :data:`sys._xoptions`. @@ -676,8 +715,8 @@ Function to initialize Python: The caller is responsible to handle exceptions (error or exit) using :c:func:`PyStatus_Exception` and :c:func:`Py_ExitStatusException`. -``PyImport_FrozenModules``, ``PyImport_AppendInittab()`` or -``PyImport_ExtendInittab()`` is used: they must be set or called after Python +If ``PyImport_FrozenModules``, ``PyImport_AppendInittab()`` or +``PyImport_ExtendInittab()`` are used, they must be set or called after Python preinitialization and before the Python initialization. Example setting the program name:: @@ -685,12 +724,9 @@ Example setting the program name:: void init_python(void) { PyStatus status; - PyConfig config; - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - goto fail; - } + PyConfig config; + PyConfig_InitPythonConfig(&config); /* Set the program name. Implicitly preinitialize Python. */ status = PyConfig_SetString(&config, &config.program_name, @@ -717,12 +753,9 @@ configuration, and then override some parameters:: PyStatus init_python(const char *program_name) { PyStatus status; - PyConfig config; - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - goto done; - } + PyConfig config; + PyConfig_InitPythonConfig(&config); /* Set the program name before reading the configuraton (decode byte string from the locale encoding). @@ -742,7 +775,7 @@ configuration, and then override some parameters:: /* Append our custom search path to sys.path */ status = PyWideStringList_Append(&config.module_search_paths, - L"/path/to/more/modules"); + L"/path/to/more/modules"); if (PyStatus_Exception(status)) { goto done; } @@ -773,9 +806,9 @@ isolate Python from the system. For example, to embed Python into an application. This configuration ignores global configuration variables, environments -variables and command line arguments (:c:member:`PyConfig.argv` is not parsed). -The C standard streams (ex: ``stdout``) and the LC_CTYPE locale are left -unchanged by default. +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:`Path Configuration ` ("output fields") to ignore these @@ -803,14 +836,10 @@ Example of customized Python always running in isolated mode:: int main(int argc, char **argv) { - PyConfig config; PyStatus status; - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - goto fail; - } - + PyConfig config; + PyConfig_InitPythonConfig(&config); config.isolated = 1; /* Decode command line arguments. @@ -846,27 +875,38 @@ Path Configuration :c:type:`PyConfig` contains multiple fields for the path configuration: -* Path configuration input fields: +* Path configuration inputs: * :c:member:`PyConfig.home` - * :c:member:`PyConfig.pythonpath_env` * :c:member:`PyConfig.pathconfig_warnings` + * :c:member:`PyConfig.program_name` + * :c:member:`PyConfig.pythonpath_env` + * current working directory: to get absolute paths + * ``PATH`` environment variable to get the program full path + (from :c:member:`PyConfig.program_name`) + * ``__PYVENV_LAUNCHER__`` environment variable + * (Windows only) Application paths in the registry under + "Software\Python\PythonCore\X.Y\PythonPath" of HKEY_CURRENT_USER and + HKEY_LOCAL_MACHINE (where X.Y is the Python version). * Path configuration output fields: + * :c:member:`PyConfig.base_exec_prefix` + * :c:member:`PyConfig.base_executable` + * :c:member:`PyConfig.base_prefix` * :c:member:`PyConfig.exec_prefix` * :c:member:`PyConfig.executable` - * :c:member:`PyConfig.prefix` * :c:member:`PyConfig.module_search_paths_set`, :c:member:`PyConfig.module_search_paths` + * :c:member:`PyConfig.prefix` -If at least one "output field" is not set, Python computes the path +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` is overriden and +:c:member:`~PyConfig.module_search_paths` is overridden and :c:member:`~PyConfig.module_search_paths_set` is set to 1. -It is possible to completely ignore the function computing the default +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 @@ -874,7 +914,7 @@ fields listed above. A string is considered as set even if it is non-empty. configuration input fields are ignored as well. Set :c:member:`~PyConfig.pathconfig_warnings` to 0 to suppress warnings when -computing the path configuration (Unix only, Windows does not log any warning). +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` fields are not set, they inherit their value from :c:member:`~PyConfig.prefix` @@ -905,6 +945,9 @@ The following configuration files are used by the path configuration: * ``python._pth`` (Windows only) * ``pybuilddir.txt`` (Unix only) +The ``__PYVENV_LAUNCHER__`` environment variable is used to set +:c:member:`PyConfig.base_executable` + Py_RunMain() ------------ @@ -938,7 +981,7 @@ initialization, the core feature of the :pep:`432`: * Builtin exceptions; * Builtin and frozen modules; * The :mod:`sys` module is only partially initialized - (ex: :data:`sys.path` doesn't exist yet); + (ex: :data:`sys.path` doesn't exist yet). * "Main" initialization phase, Python is fully initialized: @@ -964,9 +1007,9 @@ No module is imported during the "Core" phase and the ``importlib`` module is not configured: the :ref:`Path Configuration ` is only 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 sys.meta_path importer or an import hook, etc. +install a custom :data:`sys.meta_path` importer or an import hook, etc. -It may become possible to compute the :ref:`Path Configuration +It may become possible to calculatin the :ref:`Path Configuration ` in Python, after the Core phase and before the Main phase, which is one of the :pep:`432` motivation. @@ -981,14 +1024,9 @@ phases:: void init_python(void) { PyStatus status; - PyConfig config; - - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - PyConfig_Clear(&config); - Py_ExitStatusException(status); - } + PyConfig config; + PyConfig_InitPythonConfig(&config); config._init_main = 0; /* ... customize 'config' configuration ... */ diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index a1c8d34a7ea02f..80eebd89ad3f25 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -69,10 +69,12 @@ standard headers) have one of the prefixes ``Py`` or ``_Py``. Names beginning with ``_Py`` are for internal use by the Python implementation and should not be used by extension writers. Structure member names do not have a reserved prefix. -**Important:** user code should never define names that begin with ``Py`` or -``_Py``. This confuses the reader, and jeopardizes the portability of the user -code to future Python versions, which may define additional names beginning with -one of these prefixes. +.. note:: + + User code should never define names that begin with ``Py`` or ``_Py``. This + confuses the reader, and jeopardizes the portability of the user code to + future Python versions, which may define additional names beginning with one + of these prefixes. The header files are typically installed with Python. On Unix, these are located in the directories :file:`{prefix}/include/pythonversion/` and @@ -90,9 +92,9 @@ multi-platform builds since the platform independent headers under :envvar:`prefix` include the platform specific headers from :envvar:`exec_prefix`. -C++ users should note that though the API is defined entirely using C, the -header files do properly declare the entry points to be ``extern "C"``, so there -is no need to do anything special to use the API from C++. +C++ users should note that although the API is defined entirely using C, the +header files properly declare the entry points to be ``extern "C"``. As a result, +there is no need to do anything special to use the API from C++. Useful macros diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst index 279783a243a108..646f29d08a04b9 100644 --- a/Doc/c-api/list.rst +++ b/Doc/c-api/list.rst @@ -59,9 +59,9 @@ List Objects .. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) Return the object at position *index* in the list pointed to by *list*. The - position must be positive, indexing from the end of the list is not - supported. If *index* is out of bounds, return *NULL* and set an - :exc:`IndexError` exception. + position must be non-negative; indexing from the end of the list is not + supported. If *index* is out of bounds (<0 or >=len(list)), + return *NULL* and set an :exc:`IndexError` exception. .. c:function:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) @@ -71,8 +71,9 @@ List Objects .. c:function:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item) - Set the item at index *index* in list to *item*. Return ``0`` on success - or ``-1`` on failure. + Set the item at index *index* in list to *item*. Return ``0`` on success. + If *index* is out of bounds, return ``-1`` and set an :exc:`IndexError` + exception. .. note:: @@ -111,8 +112,7 @@ List Objects Return a list of the objects in *list* containing the objects *between* *low* and *high*. Return *NULL* and set an exception if unsuccessful. Analogous - to ``list[low:high]``. Negative indices, as when slicing from Python, are not - supported. + to ``list[low:high]``. Indexing from the end of the list is not supported. .. c:function:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist) @@ -120,8 +120,8 @@ List Objects Set the slice of *list* between *low* and *high* to the contents of *itemlist*. Analogous to ``list[low:high] = itemlist``. The *itemlist* may be *NULL*, indicating the assignment of an empty list (slice deletion). - Return ``0`` on success, ``-1`` on failure. Negative indices, as when - slicing from Python, are not supported. + Return ``0`` on success, ``-1`` on failure. Indexing from the end of the + list is not supported. .. c:function:: int PyList_Sort(PyObject *list) diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 6be29f9cd32eaa..fdaefafe21ba09 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -288,7 +288,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. If the value of *obj* is out of range for an :c:type:`unsigned long`, return the reduction of that value modulo ``ULONG_MAX + 1``. - Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate. + Returns ``(unsigned long)-1`` on error. Use :c:func:`PyErr_Occurred` to + disambiguate. .. versionchanged:: 3.8 Use :meth:`__index__` if available. @@ -307,7 +308,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. If the value of *obj* is out of range for an :c:type:`unsigned long long`, return the reduction of that value modulo ``PY_ULLONG_MAX + 1``. - Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate. + Returns ``(unsigned long long)-1`` on error. Use :c:func:`PyErr_Occurred` + to disambiguate. .. versionchanged:: 3.8 Use :meth:`__index__` if available. diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index ab49e48782d71a..d3c8b30d360ec2 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -67,7 +67,7 @@ example:: In this example, the memory request for the I/O buffer is handled by the C library allocator. The Python memory manager is involved only in the allocation -of the string object returned as a result. +of the bytes object returned as a result. In most situations, however, it is recommended to allocate memory from the Python heap specifically because the latter is under control of the Python @@ -472,7 +472,7 @@ Customize Memory Allocators if the GIL is held when functions of :c:data:`PYMEM_DOMAIN_OBJ` and :c:data:`PYMEM_DOMAIN_MEM` domains are called. - .. versionchanged:: 3.8.0 + .. versionchanged:: 3.8 Byte patterns ``0xCB`` (``CLEANBYTE``), ``0xDB`` (``DEADBYTE``) and ``0xFB`` (``FORBIDDENBYTE``) have been replaced with ``0xCD``, ``0xDD`` and ``0xFD`` to use the same values than Windows CRT debug ``malloc()`` diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 68cbda2938f3f0..feca1ec2a057ad 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -417,7 +417,22 @@ state: Add an object to *module* as *name*. This is a convenience function which can be used from the module's initialization function. This steals a reference to - *value*. Return ``-1`` on error, ``0`` on success. + *value* on success. Return ``-1`` on error, ``0`` on success. + + .. note:: + + Unlike other functions that steal references, ``PyModule_AddObject()`` only + decrements the reference count of *value* **on success**. + + This means that its return value must be checked, and calling code must + :c:func:`Py_DECREF` *value* manually on error. Example usage:: + + Py_INCREF(spam); + if (PyModule_AddObject(module, "spam", spam) < 0) { + Py_DECREF(module); + Py_DECREF(spam); + return NULL; + } .. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value) diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index ce0d05942f4e79..187a025a67cb6d 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -261,7 +261,8 @@ Object Protocol *args* must not be *NULL*, use an empty tuple if no arguments are needed. If no named arguments are needed, *kwargs* can be *NULL*. - Returns the result of the call on success, or *NULL* on failure. + Return the result of the call on success, or raise an exception and return + *NULL* on failure. This is the equivalent of the Python expression: ``callable(*args, **kwargs)``. @@ -272,7 +273,8 @@ Object Protocol Call a callable Python object *callable*, with arguments given by the tuple *args*. If no arguments are needed, then *args* can be *NULL*. - Returns the result of the call on success, or *NULL* on failure. + Return the result of the call on success, or raise an exception and return + *NULL* on failure. This is the equivalent of the Python expression: ``callable(*args)``. @@ -283,7 +285,8 @@ Object Protocol The C arguments are described using a :c:func:`Py_BuildValue` style format string. The format can be *NULL*, indicating that no arguments are provided. - Returns the result of the call on success, or *NULL* on failure. + Return the result of the call on success, or raise an exception and return + *NULL* on failure. This is the equivalent of the Python expression: ``callable(*args)``. @@ -302,7 +305,8 @@ Object Protocol The format can be *NULL*, indicating that no arguments are provided. - Returns the result of the call on success, or *NULL* on failure. + Return the result of the call on success, or raise an exception and return + *NULL* on failure. This is the equivalent of the Python expression: ``obj.name(arg1, arg2, ...)``. @@ -320,7 +324,8 @@ Object Protocol :c:type:`PyObject\*` arguments. The arguments are provided as a variable number of parameters followed by *NULL*. - Returns the result of the call on success, or *NULL* on failure. + Return the result of the call on success, or raise an exception and return + *NULL* on failure. This is the equivalent of the Python expression: ``callable(arg1, arg2, ...)``. @@ -331,7 +336,9 @@ Object Protocol Calls a method of the Python object *obj*, where the name of the method is given as a Python string object in *name*. It is called with a variable number of :c:type:`PyObject\*` arguments. The arguments are provided as a variable number - of parameters followed by *NULL*. Returns the result of the call on success, or + of parameters followed by *NULL*. + + Return the result of the call on success, or raise an exception and return *NULL* on failure. @@ -355,7 +362,8 @@ Object Protocol *kwnames* must contain only objects of type ``str`` (not a subclass), and all keys must be unique. - Return the result of the call on success, or *NULL* on failure. + Return the result of the call on success, or raise an exception and return + *NULL* on failure. This uses the vectorcall protocol if the callable supports it; otherwise, the arguments are converted to use diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst index d11a2dde54dd9e..fe1c252ce9ba3a 100644 --- a/Doc/c-api/sequence.rst +++ b/Doc/c-api/sequence.rst @@ -130,10 +130,17 @@ Sequence Protocol .. c:function:: PyObject* PySequence_Fast(PyObject *o, const char *m) - Return the sequence or iterable *o* as a list, unless it is already a tuple or list, in - which case *o* is returned. Use :c:func:`PySequence_Fast_GET_ITEM` to access - the members of the result. Returns *NULL* on failure. If the object is not - a sequence or iterable, raises :exc:`TypeError` with *m* as the message text. + Return the sequence or iterable *o* as an object usable by the other + ``PySequence_Fast*`` family of functions. If the object is not a sequence or + iterable, raises :exc:`TypeError` with *m* as the message text. Returns + *NULL* on failure. + + The ``PySequence_Fast*`` functions are thus named because they assume + *o* is a :c:type:`PyTupleObject` or a :c:type:`PyListObject` and access + the data fields of *o* directly. + + As a CPython implementation detail, if *o* is already a sequence or list, it + will be returned. .. c:function:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o) @@ -141,8 +148,8 @@ 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 - :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list - or tuple. + :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a + list or tuple. .. c:function:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i) @@ -163,7 +170,7 @@ Sequence Protocol .. c:function:: PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i) - Return the *i*\ th element of *o* or *NULL* on failure. Macro form of + Return the *i*\ th element of *o* or *NULL* on failure. Faster form of :c:func:`PySequence_GetItem` but without checking that :c:func:`PySequence_Check` on *o* is true and without adjustment for negative indices. diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 5e0cfd0264f931..5184ad511cd9b1 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -114,10 +114,20 @@ the definition of all other Python objects. .. c:type:: PyCFunctionWithKeywords - Type of the functions used to implement Python callables in C that take - keyword arguments: they take three :c:type:`PyObject\*` parameters and return - one such value. See :c:type:`PyCFunction` above for the meaning of the return - value. + Type of the functions used to implement Python callables in C + with signature :const:`METH_VARARGS | METH_KEYWORDS`. + + +.. c:type:: _PyCFunctionFast + + Type of the functions used to implement Python callables in C + with signature :const:`METH_FASTCALL`. + + +.. c:type:: _PyCFunctionFastWithKeywords + + Type of the functions used to implement Python callables in C + with signature :const:`METH_FASTCALL | METH_KEYWORDS`. .. c:type:: PyMethodDef @@ -149,10 +159,11 @@ specific C type of the *self* object. The :attr:`ml_flags` field is a bitfield which can include the following flags. The individual flags indicate either a calling convention or a binding -convention. Of the calling convention flags, only :const:`METH_VARARGS` and -:const:`METH_KEYWORDS` can be combined. Any of the calling convention flags -can be combined with a binding flag. +convention. +There are four basic calling conventions for positional arguments +and two of them can be combined with :const:`METH_KEYWORDS` to support +also keyword arguments. So there are a total of 6 calling conventions: .. data:: METH_VARARGS @@ -164,13 +175,41 @@ can be combined with a binding flag. using :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_UnpackTuple`. -.. data:: METH_KEYWORDS +.. data:: METH_VARARGS | METH_KEYWORDS Methods with these flags must be of type :c:type:`PyCFunctionWithKeywords`. - The function expects three parameters: *self*, *args*, and a dictionary of - all the keyword arguments. The flag must be combined with - :const:`METH_VARARGS`, and the parameters are typically processed using - :c:func:`PyArg_ParseTupleAndKeywords`. + The function expects three parameters: *self*, *args*, *kwargs* where + *kwargs* is a dictionary of all the keyword arguments or possibly *NULL* + if there are no keyword arguments. The parameters are typically processed + using :c:func:`PyArg_ParseTupleAndKeywords`. + + +.. data:: METH_FASTCALL + + Fast calling convention supporting only positional arguments. + The methods have the type :c:type:`_PyCFunctionFast`. + The first parameter is *self*, the second parameter is a C array + of :c:type:`PyObject\*` values indicating the arguments and the third + parameter is the number of arguments (the length of the array). + + This is not part of the :ref:`limited API `. + + .. versionadded:: 3.7 + + +.. data:: METH_FASTCALL | METH_KEYWORDS + + Extension of :const:`METH_FASTCALL` supporting also keyword arguments, + with methods of type :c:type:`_PyCFunctionFastWithKeywords`. + Keyword arguments are passed the same way as in the vectorcall protocol: + there is an additional fourth :c:type:`PyObject\*` parameter + which is a tuple representing the names of the keyword arguments + or possibly *NULL* if there are no keywords. The values of the keyword + arguments are stored in the *args* array, after the positional arguments. + + This is not part of the :ref:`limited API `. + + .. versionadded:: 3.7 .. data:: METH_NOARGS diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index 7d870a8d4e4a71..87d2bd13d31b80 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -291,8 +291,6 @@ accessible to C code. They all work with the current interpreter thread's .. c:function:: int PySys_Audit(const char *event, const char *format, ...) - .. index:: single: audit events - Raises an auditing event with any active hooks. Returns zero for success and non-zero with an exception set on failure. @@ -311,8 +309,6 @@ accessible to C code. They all work with the current interpreter thread's .. c:function:: int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) - .. index:: single: audit events - Adds to the collection of active auditing hooks. Returns zero for success and non-zero on failure. If the runtime has been initialized, also sets an error on failure. Hooks added through this API are called for all @@ -334,7 +330,16 @@ accessible to C code. They all work with the current interpreter thread's See :pep:`578` for a detailed description of auditing. Functions in the runtime and standard library that raise events include the details in each - function's documentation. + function's documentation and listed in the :ref:`audit events table + `. + + .. audit-event:: sys.addaudithook "" c.PySys_AddAuditHook + + If the interpreter is initialized, this function raises a auditing event + ``sys.addaudithook`` with no arguments. If any existing hooks raise an + exception derived from :class:`Exception`, the new hook will not be + added and the exception is cleared. As a result, callers cannot assume + that their hook has been added unless they control all existing hooks. .. versionadded:: 3.8 diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst index 259ec4fb48515b..a0d53e2030e633 100644 --- a/Doc/c-api/tuple.rst +++ b/Doc/c-api/tuple.rst @@ -57,7 +57,7 @@ Tuple Objects .. c:function:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos) Return the object at position *pos* in the tuple pointed to by *p*. If *pos* is - out of bounds, return *NULL* and sets an :exc:`IndexError` exception. + out of bounds, return *NULL* and set an :exc:`IndexError` exception. .. c:function:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos) @@ -67,18 +67,21 @@ Tuple Objects .. c:function:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high) - Take a slice of the tuple pointed to by *p* from *low* to *high* and return it - as a new tuple. + Return the slice of the tuple pointed to by *p* between *low* and *high*, + or *NULL* on failure. This is the equivalent of the Python expression + ``p[low:high]``. Indexing from the end of the list is not supported. .. c:function:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) Insert a reference to object *o* at position *pos* of the tuple pointed to by - *p*. Return ``0`` on success. + *p*. Return ``0`` on success. If *pos* is out of bounds, return ``-1`` + and set an :exc:`IndexError` exception. .. note:: - This function "steals" a reference to *o*. + This function "steals" a reference to *o* and discards a reference to + an item already in the tuple at the affected position. .. c:function:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o) @@ -88,7 +91,10 @@ Tuple Objects .. note:: - This function "steals" a reference to *o*. + This macro "steals" a reference to *o*, and, unlike + :c:func:`PyTuple_SetItem`, does *not* discard a reference to any item that + is being replaced; any reference in the tuple at position *pos* will be + leaked. .. c:function:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 8f8367ab77c8c4..239355a802413e 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -118,7 +118,8 @@ The following functions and structs are used to create .. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) - Creates and returns a heap type object from the *spec*. + Creates and returns a heap type object from the *spec* + (:const:`Py_TPFLAGS_HEAPTYPE`). If *bases* is a tuple, the created heap type contains all types contained in it as base types. @@ -142,10 +143,6 @@ The following functions and structs are used to create Name of the type, used to set :c:member:`PyTypeObject.tp_name`. - .. c:member:: const char* PyType_Spec.doc - - Type docstring, used to set :c:member:`PyTypeObject.tp_doc`. - .. c:member:: int PyType_Spec.basicsize .. c:member:: int PyType_Spec.itemsize diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 83fcc5abed7079..bb767500743098 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -20,7 +20,7 @@ functionality. The fields of the type object are examined in detail in this section. The fields will be described in the order in which they occur in the structure. -In addition to the following quick reference, the :ref:`examples` +In addition to the following quick reference, the :ref:`typedef-examples` section provides at-a-glance insight into the meaning and use of :c:type:`PyTypeObject`. @@ -285,7 +285,7 @@ sub-slots +---------------------------------------------------------+-----------------------------------+--------------+ | :c:member:`~PyNumberMethods.nb_inplace_true_divide` | :c:type:`binaryfunc` | __truediv__ | +---------------------------------------------------------+-----------------------------------+--------------+ - | :c:member:`~PyNumberMethods.nb_index` | :c:type:`binaryfunc` | __index__ | + | :c:member:`~PyNumberMethods.nb_index` | :c:type:`unaryfunc` | __index__ | +---------------------------------------------------------+-----------------------------------+--------------+ | :c:member:`~PyNumberMethods.nb_matrix_multiply` | :c:type:`binaryfunc` | __matmul__ | | | | __rmatmul__ | @@ -654,9 +654,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) the instance is still in existence, but there are no references to it. The destructor function should free all references which the instance owns, free all memory buffers owned by the instance (using the freeing function corresponding - to the allocation function used to allocate the buffer), and finally (as its - last action) call the type's :c:member:`~PyTypeObject.tp_free` function. If the type is not - subtypable (doesn't have the :const:`Py_TPFLAGS_BASETYPE` flag bit set), it is + to the allocation function used to allocate the buffer), and call the type's + :c:member:`~PyTypeObject.tp_free` function. If the type is not subtypable + (doesn't have the :const:`Py_TPFLAGS_BASETYPE` flag bit set), it is permissible to call the object deallocator directly instead of via :c:member:`~PyTypeObject.tp_free`. The object deallocator should be the one used to allocate the instance; this is normally :c:func:`PyObject_Del` if the instance was allocated @@ -664,6 +664,21 @@ and :c:type:`PyType_Type` effectively act as defaults.) :c:func:`PyObject_GC_Del` if the instance was allocated using :c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`. + Finally, if the type is heap allocated (:const:`Py_TPFLAGS_HEAPTYPE`), the + deallocator should decrement the reference count for its type object after + calling the type deallocator. In order to avoid dangling pointers, the + recommended way to achieve this is: + + .. code-block:: c + + static void foo_dealloc(foo_object *self) { + PyTypeObject *tp = Py_TYPE(self); + // free references and buffers here + tp->tp_free(self); + Py_DECREF(tp); + } + + **Inheritance:** This field is inherited by subtypes. @@ -1021,7 +1036,8 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. data:: Py_TPFLAGS_HEAPTYPE - This bit is set when the type object itself is allocated on the heap. In this + This bit is set when the type object itself is allocated on the heap, for + example, types created dynamically using :c:func:`PyType_FromSpec`. In this case, the :attr:`ob_type` field of its instances is considered a reference to the type, and the type object is INCREF'ed when a new instance is created, and DECREF'ed when an instance is destroyed (this does not apply to instances of @@ -1311,12 +1327,6 @@ and :c:type:`PyType_Type` effectively act as defaults.) ``Py_NotImplemented``, if another error occurred it must return *NULL* and set an exception condition. - .. note:: - - If you want to implement a type for which only a limited set of - comparisons makes sense (e.g. ``==`` and ``!=``, but not ``<`` and - friends), directly raise :exc:`TypeError` in the rich comparison function. - The following constants are defined to be used as the third argument for :c:member:`~PyTypeObject.tp_richcompare` and for :c:func:`PyObject_RichCompare`: @@ -2450,7 +2460,7 @@ Slot Type typedefs .. c:type:: int (*objobjargproc)(PyObject *, PyObject *, PyObject *) -.. _examples: +.. _typedef-examples: Examples ======== diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 3fe0ae47aac35a..67dc11dfa9a537 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -335,12 +335,12 @@ the same library that the Python runtime is using. .. c:function:: PyObject* PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) - This is the main, unvarnished function of Python interpretation. It is - literally 2000 lines long. The code object associated with the execution - frame *f* is executed, interpreting bytecode and executing calls as needed. - The additional *throwflag* parameter can mostly be ignored - if true, then - it causes an exception to immediately be thrown; this is used for the - :meth:`~generator.throw` methods of generator objects. + This is the main, unvarnished function of Python interpretation. The code + object associated with the execution frame *f* is executed, interpreting + bytecode and executing calls as needed. The additional *throwflag* + parameter can mostly be ignored - if true, then it causes an exception + to immediately be thrown; this is used for the :meth:`~generator.throw` + methods of generator objects. .. versionchanged:: 3.4 This function now includes a debug assertion to help ensure that it @@ -388,11 +388,22 @@ the same library that the Python runtime is using. Whenever ``PyCompilerFlags *flags`` is *NULL*, :attr:`cf_flags` is treated as equal to ``0``, and any modification due to ``from __future__ import`` is - discarded. :: + discarded. - struct PyCompilerFlags { - int cf_flags; - } + .. c:member:: int cf_flags + + Compiler flags. + + .. c:member:: int cf_feature_version + + *cf_feature_version* is the minor Python version. It should be + initialized to ``PY_MINOR_VERSION``. + + The field is ignored by default, it is used if and only if + ``PyCF_ONLY_AST`` flag is set in *cf_flags*. + + .. versionchanged:: 3.8 + Added *cf_feature_version* field. .. c:var:: int CO_FUTURE_DIVISION diff --git a/Doc/conf.py b/Doc/conf.py index e85ea5b2d2ff49..abaa760c98c1aa 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -48,8 +48,10 @@ needs_sphinx = '1.8' # Ignore any .rst files in the venv/ directory. -venvdir = os.getenv('VENVDIR', 'venv') -exclude_patterns = [venvdir+'/*', 'README.rst'] +exclude_patterns = ['venv/*', 'README.rst'] +venvdir = os.getenv('VENVDIR') +if venvdir is not None: + exclude_patterns.append(venvdir + '/*') # Disable Docutils smartquotes for several translations smartquotes_excludes = { diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index aca57a1dae9d8c..cfed1bd503118e 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -234,9 +234,26 @@ PyCode_Check:PyObject*:co:0: PyCode_GetNumFree:int::: PyCode_GetNumFree:PyCodeObject*:co:0: +PyCode_NewWithPosOnlyArgs:PyCodeObject*::+1: +PyCode_NewWithPosOnlyArgs:int:argcount:: +PyCode_NewWithPosOnlyArgs:int:posonlyargcount:: +PyCode_NewWithPosOnlyArgs:int:kwonlyargcount:: +PyCode_NewWithPosOnlyArgs:int:nlocals:: +PyCode_NewWithPosOnlyArgs:int:stacksize:: +PyCode_NewWithPosOnlyArgs:int:flags:: +PyCode_NewWithPosOnlyArgs:PyObject*:code:0: +PyCode_NewWithPosOnlyArgs:PyObject*:consts:0: +PyCode_NewWithPosOnlyArgs:PyObject*:names:0: +PyCode_NewWithPosOnlyArgs:PyObject*:varnames:0: +PyCode_NewWithPosOnlyArgs:PyObject*:freevars:0: +PyCode_NewWithPosOnlyArgs:PyObject*:cellvars:0: +PyCode_NewWithPosOnlyArgs:PyObject*:filename:0: +PyCode_NewWithPosOnlyArgs:PyObject*:name:0: +PyCode_NewWithPosOnlyArgs:int:firstlineno:: +PyCode_NewWithPosOnlyArgs:PyObject*:lnotab:0: + PyCode_New:PyCodeObject*::+1: PyCode_New:int:argcount:: -PyCode_New:int:posonlyargcount:: PyCode_New:int:kwonlyargcount:: PyCode_New:int:nlocals:: PyCode_New:int:stacksize:: @@ -2445,7 +2462,7 @@ PyUnicode_FromWideChar:Py_ssize_t:size:: PyUnicode_AsWideChar:Py_ssize_t::: PyUnicode_AsWideChar:PyObject*:*unicode:0: PyUnicode_AsWideChar:wchar_t*:w:: -PyUnicode_AsWideChar:Pyssize_t:size:: +PyUnicode_AsWideChar:Py_ssize_t:size:: PyUnicode_AsWideCharString:wchar_t*::: PyUnicode_AsWideCharString:PyObject*:unicode:0: diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst index 2e46c7ac8635e8..5f7b3bbc4f9174 100644 --- a/Doc/distributing/index.rst +++ b/Doc/distributing/index.rst @@ -40,7 +40,7 @@ Key terms evolution of the standard packaging tools and the associated metadata and file format standards. They maintain a variety of tools, documentation and issue trackers on both `GitHub `__ and - `BitBucket `__. + `Bitbucket `__. * :mod:`distutils` is the original build and distribution system first added to the Python standard library in 1998. While direct use of :mod:`distutils` is being phased out, it still laid the foundation for the current packaging @@ -148,7 +148,7 @@ These are quick answers or links for some common tasks. This isn't an easy topic, but here are a few tips: * check the Python Packaging Index to see if the name is already in use -* check popular hosting sites like GitHub, BitBucket, etc to see if there +* check popular hosting sites like GitHub, Bitbucket, etc to see if there is already a project with that name * check what comes up in a web search for the name you're considering * avoid particularly common words, especially ones with multiple meanings, diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst index 2601d30f63eb4c..a42d2d3559f2b2 100644 --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -6,12 +6,12 @@ API Reference .. seealso:: - `New and changed setup.py arguments in setuptools `_ + `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. -.. _setuptools-setup-py: https://setuptools.readthedocs.io/en/latest/setuptools.html#new-and-changed-setup-keywords +.. _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 @@ -1863,6 +1863,9 @@ Subclasses of :class:`Command` must define the following methods. .. module:: distutils.command.bdist_wininst :synopsis: Build a Windows installer +.. deprecated:: 3.8 + Use bdist_wheel (wheel packages) instead. + .. % todo diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst index f44d0d039f45f4..b814f2e9508c9c 100644 --- a/Doc/distutils/builtdist.rst +++ b/Doc/distutils/builtdist.rst @@ -146,6 +146,9 @@ generated by each, are: | :command:`bdist_msi` | msi | +--------------------------+-------------------------------------+ +.. note:: + bdist_wininst is deprecated since Python 3.8. + The following sections give details on the individual :command:`bdist_\*` commands. @@ -298,6 +301,9 @@ file winds up deep in the "build tree," in a temporary directory created by Creating Windows Installers =========================== +.. warning:: + bdist_wininst is deprecated since Python 3.8. + Executable installers are the natural format for binary distributions on Windows. They display a nice graphical user interface, display some information about the module distribution to be installed taken from the metadata in the @@ -315,8 +321,8 @@ or the :command:`bdist` command with the :option:`!--formats` option:: If you have a pure module distribution (only containing pure Python modules and packages), the resulting installer will be version independent and have a name -like :file:`foo-1.0.win32.exe`. These installers can even be created on Unix -platforms or Mac OS X. +like :file:`foo-1.0.win32.exe`. Note that creating ``wininst`` binary +distributions in only supported on Windows systems. If you have a non-pure distribution, the extensions can only be created on a Windows platform, and will be Python version dependent. The installer filename @@ -459,3 +465,6 @@ Starting with Python 2.6, bdist_wininst supports a :option:`!--user-access-contr option. The default is 'none' (meaning no UAC handling is done), and other valid values are 'auto' (meaning prompt for UAC elevation if Python was installed for all users) and 'force' (meaning always prompt for elevation). + +.. note:: + bdist_wininst is deprecated since Python 3.8. diff --git a/Doc/distutils/examples.rst b/Doc/distutils/examples.rst index 4ac552c7c6997a..44f70831d0bf87 100644 --- a/Doc/distutils/examples.rst +++ b/Doc/distutils/examples.rst @@ -1,8 +1,8 @@ .. _distutils_examples: -******** -Examples -******** +****************** +Distutils Examples +****************** .. include:: ./_setuptools_disclaimer.rst diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index e459514b2b5853..5b4ea8220e237e 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -209,7 +209,7 @@ usually declare a static object variable at the beginning of your file:: static PyObject *SpamError; and initialize it in your module's initialization function (:c:func:`PyInit_spam`) -with an exception object (leaving out the error checking for now):: +with an exception object:: PyMODINIT_FUNC PyInit_spam(void) @@ -221,8 +221,14 @@ with an exception object (leaving out the error checking for now):: return NULL; SpamError = PyErr_NewException("spam.error", NULL, NULL); - Py_INCREF(SpamError); - PyModule_AddObject(m, "error", SpamError); + Py_XINCREF(SpamError); + if (PyModule_AddObject(m, "error", SpamError) < 0) { + Py_XDECREF(SpamError); + Py_CLEAR(SpamError); + Py_DECREF(m); + return NULL; + } + return m; } @@ -1261,8 +1267,12 @@ function must take care of initializing the C API pointer array:: /* Create a Capsule containing the API pointer array's address */ c_api_object = PyCapsule_New((void *)PySpam_API, "spam._C_API", NULL); - if (c_api_object != NULL) - PyModule_AddObject(m, "_C_API", c_api_object); + if (PyModule_AddObject(m, "_C_API", c_api_object) < 0) { + Py_XDECREF(c_api_object); + Py_DECREF(m); + return NULL; + } + return m; } diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index 59c8cc01222b2c..b2c819c8582376 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -179,7 +179,12 @@ This initializes the :class:`Custom` type, filling in a number of members to the appropriate default values, including :attr:`ob_type` that we initially set to *NULL*. :: - PyModule_AddObject(m, "Custom", (PyObject *) &CustomType); + Py_INCREF(&CustomType); + if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { + Py_DECREF(&CustomType); + Py_DECREF(m); + return NULL; + } This adds the type to the module dictionary. This allows us to create :class:`Custom` instances by calling the :class:`Custom` class: @@ -864,7 +869,12 @@ function:: return NULL; Py_INCREF(&SubListType); - PyModule_AddObject(m, "SubList", (PyObject *) &SubListType); + if (PyModule_AddObject(m, "SubList", (PyObject *) &SubListType) < 0) { + Py_DECREF(&SubListType); + Py_DECREF(m); + return NULL; + } + return m; } diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index e2d63a0323da66..81c0f474ac1624 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -149,66 +149,15 @@ to tell Python which namespace to use. Why can't I use an assignment in an expression? ----------------------------------------------- -Many people used to C or Perl complain that they want to use this C idiom: +Starting in Python 3.8, you can! -.. code-block:: c +Assignment expressions using the walrus operator `:=` assign a variable in an +expression:: - while (line = readline(f)) { - // do something with line - } - -where in Python you're forced to write this:: - - while True: - line = f.readline() - if not line: - break - ... # do something with line - -The reason for not allowing assignment in Python expressions is a common, -hard-to-find bug in those other languages, caused by this construct: - -.. code-block:: c - - if (x = 0) { - // error handling - } - else { - // code that only works for nonzero x - } - -The error is a simple typo: ``x = 0``, which assigns 0 to the variable ``x``, -was written while the comparison ``x == 0`` is certainly what was intended. - -Many alternatives have been proposed. Most are hacks that save some typing but -use arbitrary or cryptic syntax or keywords, and fail the simple criterion for -language change proposals: it should intuitively suggest the proper meaning to a -human reader who has not yet been introduced to the construct. - -An interesting phenomenon is that most experienced Python programmers recognize -the ``while True`` idiom and don't seem to be missing the assignment in -expression construct much; it's only newcomers who express a strong desire to -add this to the language. - -There's an alternative way of spelling this that seems attractive but is -generally less robust than the "while True" solution:: - - line = f.readline() - while line: - ... # do something with line... - line = f.readline() - -The problem with this is that if you change your mind about exactly how you get -the next line (e.g. you want to change it into ``sys.stdin.readline()``) you -have to remember to change two places in your program -- the second occurrence -is hidden at the bottom of the loop. - -The best approach is to use iterators, making it possible to loop through -objects using the ``for`` statement. For example, :term:`file objects -` support the iterator protocol, so you can write simply:: + while chunk := fp.read(200): + print(chunk) - for line in f: - ... # do something with line... +See :pep:`572` for more information. diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index a00c6a053ef120..9d45765abaacf2 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -659,7 +659,7 @@ How can my code discover the name of an object? ----------------------------------------------- Generally speaking, it can't, because objects don't really have names. -Essentially, assignment always binds a name to a value; The same is true of +Essentially, assignment always binds a name to a value; the same is true of ``def`` and ``class`` statements, but in that case the value is a callable. Consider the following code:: @@ -779,30 +779,23 @@ A slash in the argument list of a function denotes that the parameters prior to it are positional-only. Positional-only parameters are the ones without an externally-usable name. Upon calling a function that accepts positional-only parameters, arguments are mapped to parameters based solely on their position. -For example, :func:`pow` is a function that accepts positional-only parameters. -Its documentation looks like this:: +For example, :func:`divmod` is a function that accepts positional-only +parameters. Its documentation looks like this:: - >>> help(pow) - Help on built-in function pow in module builtins: + >>> help(divmod) + Help on built-in function divmod in module builtins: - pow(x, y, z=None, /) - Equivalent to x**y (with two arguments) or x**y % z (with three arguments) + divmod(x, y, /) + Return the tuple (x//y, x%y). Invariant: div*y + mod == x. - Some types, such as ints, are able to use a more efficient algorithm when - invoked using the three argument form. +The slash at the end of the parameter list means that both parameters are +positional-only. Thus, calling :func:`divmod` with keyword arguments would lead +to an error:: -The slash at the end of the parameter list means that all three parameters are -positional-only. Thus, calling :func:`pow` with keyword arguments would lead to -an error:: - - >>> pow(x=3, y=4) + >>> divmod(x=3, y=4) Traceback (most recent call last): File "", line 1, in - TypeError: pow() takes no keyword arguments - -Note that as of this writing this is only documentational and no valid syntax -in Python, although there is :pep:`570`, which proposes a syntax for -position-only parameters in Python. + TypeError: divmod() takes no keyword arguments Numbers and strings diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 0f2a3a1fdf0510..9ce0357f1cb424 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -247,7 +247,7 @@ Glossary Fortran contiguous arrays, the first index varies the fastest. coroutine - Coroutines is a more generalized form of subroutines. Subroutines are + Coroutines are a more generalized form of subroutines. Subroutines are entered at one point and exited at another point. Coroutines can be entered, exited, and resumed at many different points. They can be implemented with the :keyword:`async def` statement. See also @@ -739,17 +739,28 @@ Glossary also :term:`immutable`. named tuple - Any tuple-like class whose indexable elements are also accessible using - named attributes (for example, :func:`time.localtime` returns a - tuple-like object where the *year* is accessible either with an - index such as ``t[0]`` or with a named attribute like ``t.tm_year``). - - A named tuple can be a built-in type such as :class:`time.struct_time`, - or it can be created with a regular class definition. A full featured - named tuple can also be created with the factory function - :func:`collections.namedtuple`. The latter approach automatically - provides extra features such as a self-documenting representation like - ``Employee(name='jones', title='programmer')``. + The term "named tuple" applies to any type or class that inherits from + tuple and whose indexable elements are also accessible using named + attributes. The type or class may have other features as well. + + Several built-in types are named tuples, including the values returned + by :func:`time.localtime` and :func:`os.stat`. Another example is + :data:`sys.float_info`:: + + >>> sys.float_info[1] # indexed access + 1024 + >>> sys.float_info.max_exp # named field access + 1024 + >>> isinstance(sys.float_info, tuple) # kind of tuple + True + + Some named tuples are built-in types (such as the above examples). + Alternatively, a named tuple can be created from a regular class + definition that inherits from :class:`tuple` and that defines named + fields. Such a class can be written by hand or it can be created with + the factory function :func:`collections.namedtuple`. The latter + technique also adds some extra methods that may not be found in + hand-written or built-in named tuples. namespace The place where a variable is stored. Namespaces are implemented as @@ -1032,14 +1043,6 @@ Glossary an :term:`expression` or one of several constructs with a keyword, such as :keyword:`if`, :keyword:`while` or :keyword:`for`. - struct sequence - A tuple with named elements. Struct sequences expose an interface similar - to :term:`named tuple` in that elements can be accessed either by - index or as an attribute. However, they do not have any of the named tuple - methods like :meth:`~collections.somenamedtuple._make` or - :meth:`~collections.somenamedtuple._asdict`. Examples of struct sequences - include :data:`sys.float_info` and the return value of :func:`os.stat`. - text encoding A codec which encodes Unicode strings to bytes. diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index b29e590b20cba8..9856e6caec0928 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -117,7 +117,7 @@ The important points to remember are: * non-data descriptors may be overridden by instance dictionaries. The object returned by ``super()`` also has a custom :meth:`__getattribute__` -method for invoking descriptors. The call ``super(B, obj).m()`` searches +method for invoking descriptors. The attribute lookup ``super(B, obj).m`` searches ``obj.__class__.__mro__`` for the base class ``A`` immediately following ``B`` and then returns ``A.__dict__['m'].__get__(obj, B)``. If not a descriptor, ``m`` is returned unchanged. If not in the dictionary, ``m`` reverts to a diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 71f9fc920fdfc9..9f52780af4fc2d 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -948,6 +948,41 @@ This variant shows how you can e.g. apply configuration for particular loggers machinery in the main process (even though the logging events are generated in the worker processes) to direct the messages to the appropriate destinations. +Using concurrent.futures.ProcessPoolExecutor +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you want to use :class:`concurrent.futures.ProcessPoolExecutor` to start +your worker processes, you need to create the queue slightly differently. +Instead of + +.. code-block:: python + + queue = multiprocessing.Queue(-1) + +you should use + +.. code-block:: python + + queue = multiprocessing.Manager().Queue(-1) # also works with the examples above + +and you can then replace the worker creation from this:: + + workers = [] + for i in range(10): + worker = multiprocessing.Process(target=worker_process, + args=(queue, worker_configurer)) + workers.append(worker) + worker.start() + for w in workers: + w.join() + +to this (remembering to first import :mod:`concurrent.futures`):: + + with concurrent.futures.ProcessPoolExecutor(max_workers=10) as executor: + for i in range(10): + executor.submit(worker_process, queue, worker_configurer) + + Using file rotation ------------------- @@ -2266,9 +2301,9 @@ The script just arranges to decorate ``foo`` with a decorator which will do the conditional logging that's required. The decorator takes a logger as a parameter and attaches a memory handler for the duration of the call to the decorated function. The decorator can be additionally parameterised using a target handler, -a level at which flushing should occur, and a capacity for the buffer. These -default to a :class:`~logging.StreamHandler` which writes to ``sys.stderr``, -``logging.ERROR`` and ``100`` respectively. +a level at which flushing should occur, and a capacity for the buffer (number of +records buffered). These default to a :class:`~logging.StreamHandler` which +writes to ``sys.stderr``, ``logging.ERROR`` and ``100`` respectively. Here's the script:: @@ -2709,3 +2744,238 @@ And if we want less: In this case, the commands don't print anything to the console, since nothing at ``WARNING`` level or above is logged by them. + +.. _qt-gui: + +A Qt GUI for logging +-------------------- + +A question that comes up from time to time is about how to log to a GUI +application. The `Qt `_ framework is a popular +cross-platform UI framework with Python bindings using `PySide2 +`_ or `PyQt5 +`_ libraries. + +The following example shows how to log to a Qt GUI. This introduces a simple +``QtHandler`` class which takes a callable, which should be a slot in the main +thread that does GUI updates. A worker thread is also created to show how you +can log to the GUI from both the UI itself (via a button for manual logging) +as well as a worker thread doing work in the background (here, just logging +messages at random levels with random short delays in between). + +The worker thread is implemented using Qt's ``QThread`` class rather than the +:mod:`threading` module, as there are circumstances where one has to use +``QThread``, which offers better integration with other ``Qt`` components. + +The code should work with recent releases of either ``PySide2`` or ``PyQt5``. +You should be able to adapt the approach to earlier versions of Qt. Please +refer to the comments in the code snippet for more detailed information. + +.. code-block:: python3 + + import datetime + import logging + import random + import sys + import time + + # Deal with minor differences between PySide2 and PyQt5 + try: + from PySide2 import QtCore, QtGui, QtWidgets + Signal = QtCore.Signal + Slot = QtCore.Slot + except ImportError: + from PyQt5 import QtCore, QtGui, QtWidgets + Signal = QtCore.pyqtSignal + Slot = QtCore.pyqtSlot + + + logger = logging.getLogger(__name__) + + + # + # Signals need to be contained in a QObject or subclass in order to be correctly + # initialized. + # + class Signaller(QtCore.QObject): + signal = Signal(str, logging.LogRecord) + + # + # Output to a Qt GUI is only supposed to happen on the main thread. So, this + # handler is designed to take a slot function which is set up to run in the main + # thread. In this example, the function takes a string argument which is a + # formatted log message, and the log record which generated it. The formatted + # string is just a convenience - you could format a string for output any way + # you like in the slot function itself. + # + # You specify the slot function to do whatever GUI updates you want. The handler + # doesn't know or care about specific UI elements. + # + class QtHandler(logging.Handler): + def __init__(self, slotfunc, *args, **kwargs): + super(QtHandler, self).__init__(*args, **kwargs) + self.signaller = Signaller() + self.signaller.signal.connect(slotfunc) + + def emit(self, record): + s = self.format(record) + self.signaller.signal.emit(s, record) + + # + # This example uses QThreads, which means that the threads at the Python level + # are named something like "Dummy-1". The function below gets the Qt name of the + # current thread. + # + def ctname(): + return QtCore.QThread.currentThread().objectName() + + + # + # Used to generate random levels for logging. + # + LEVELS = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, + logging.CRITICAL) + + # + # This worker class represents work that is done in a thread separate to the + # main thread. The way the thread is kicked off to do work is via a button press + # that connects to a slot in the worker. + # + # Because the default threadName value in the LogRecord isn't much use, we add + # a qThreadName which contains the QThread name as computed above, and pass that + # value in an "extra" dictionary which is used to update the LogRecord with the + # QThread name. + # + # This example worker just outputs messages sequentially, interspersed with + # random delays of the order of a few seconds. + # + class Worker(QtCore.QObject): + @Slot() + def start(self): + extra = {'qThreadName': ctname() } + logger.debug('Started work', extra=extra) + i = 1 + # Let the thread run until interrupted. This allows reasonably clean + # thread termination. + while not QtCore.QThread.currentThread().isInterruptionRequested(): + delay = 0.5 + random.random() * 2 + time.sleep(delay) + level = random.choice(LEVELS) + logger.log(level, 'Message after delay of %3.1f: %d', delay, i, extra=extra) + i += 1 + + # + # Implement a simple UI for this cookbook example. This contains: + # + # * A read-only text edit window which holds formatted log messages + # * A button to start work and log stuff in a separate thread + # * A button to log something from the main thread + # * A button to clear the log window + # + class Window(QtWidgets.QWidget): + + COLORS = { + logging.DEBUG: 'black', + logging.INFO: 'blue', + logging.WARNING: 'orange', + logging.ERROR: 'red', + logging.CRITICAL: 'purple', + } + + def __init__(self, app): + super(Window, self).__init__() + self.app = app + self.textedit = te = QtWidgets.QPlainTextEdit(self) + # Set whatever the default monospace font is for the platform + f = QtGui.QFont('nosuchfont') + f.setStyleHint(f.Monospace) + te.setFont(f) + te.setReadOnly(True) + PB = QtWidgets.QPushButton + self.work_button = PB('Start background work', self) + self.log_button = PB('Log a message at a random level', self) + self.clear_button = PB('Clear log window', self) + self.handler = h = QtHandler(self.update_status) + # Remember to use qThreadName rather than threadName in the format string. + fs = '%(asctime)s %(qThreadName)-12s %(levelname)-8s %(message)s' + formatter = logging.Formatter(fs) + h.setFormatter(formatter) + logger.addHandler(h) + # Set up to terminate the QThread when we exit + app.aboutToQuit.connect(self.force_quit) + + # Lay out all the widgets + layout = QtWidgets.QVBoxLayout(self) + layout.addWidget(te) + layout.addWidget(self.work_button) + layout.addWidget(self.log_button) + layout.addWidget(self.clear_button) + self.setFixedSize(900, 400) + + # Connect the non-worker slots and signals + self.log_button.clicked.connect(self.manual_update) + self.clear_button.clicked.connect(self.clear_display) + + # Start a new worker thread and connect the slots for the worker + self.start_thread() + self.work_button.clicked.connect(self.worker.start) + # Once started, the button should be disabled + self.work_button.clicked.connect(lambda : self.work_button.setEnabled(False)) + + def start_thread(self): + self.worker = Worker() + self.worker_thread = QtCore.QThread() + self.worker.setObjectName('Worker') + self.worker_thread.setObjectName('WorkerThread') # for qThreadName + self.worker.moveToThread(self.worker_thread) + # This will start an event loop in the worker thread + self.worker_thread.start() + + def kill_thread(self): + # Just tell the worker to stop, then tell it to quit and wait for that + # to happen + self.worker_thread.requestInterruption() + if self.worker_thread.isRunning(): + self.worker_thread.quit() + self.worker_thread.wait() + else: + print('worker has already exited.') + + def force_quit(self): + # For use when the window is closed + if self.worker_thread.isRunning(): + self.kill_thread() + + # The functions below update the UI and run in the main thread because + # that's where the slots are set up + + @Slot(str) + def update_status(self, status, record): + color = self.COLORS.get(record.levelno, 'black') + s = '
%s
' % (color, status) + self.textedit.appendHtml(s) + + @Slot() + def manual_update(self): + # This function uses the formatted message passed in, but also uses + # information from the record to format the message in an appropriate + # color according to its severity (level). + level = random.choice(LEVELS) + extra = {'qThreadName': ctname() } + logger.log(level, 'Manually logged!', extra=extra) + + @Slot() + def clear_display(self): + self.textedit.clear() + + + def main(): + QtCore.QThread.currentThread().setObjectName('MainThread') + logging.getLogger().setLevel(logging.DEBUG) + app = QtWidgets.QApplication(sys.argv) + example = Window(app) + example.show() + sys.exit(app.exec_()) + + if __name__=='__main__': + main() diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst index 24c3235e4add94..51bd64bfc232ca 100644 --- a/Doc/howto/unicode.rst +++ b/Doc/howto/unicode.rst @@ -57,14 +57,14 @@ their corresponding code points: ... 007B '{'; LEFT CURLY BRACKET ... - 2167 'Ⅶ': ROMAN NUMERAL EIGHT - 2168 'Ⅸ': ROMAN NUMERAL NINE + 2167 'Ⅷ'; ROMAN NUMERAL EIGHT + 2168 'Ⅸ'; ROMAN NUMERAL NINE ... - 265E '♞': BLACK CHESS KNIGHT - 265F '♟': BLACK CHESS PAWN + 265E '♞'; BLACK CHESS KNIGHT + 265F '♟'; BLACK CHESS PAWN ... - 1F600 '😀': GRINNING FACE - 1F609 '😉': WINKING FACE + 1F600 '😀'; GRINNING FACE + 1F609 '😉'; WINKING FACE ... Strictly, these definitions imply that it's meaningless to say 'this is diff --git a/Doc/includes/custom.c b/Doc/includes/custom.c index 13d16f5424ae4d..bda32e2ad81d46 100644 --- a/Doc/includes/custom.c +++ b/Doc/includes/custom.c @@ -35,6 +35,11 @@ PyInit_custom(void) return NULL; Py_INCREF(&CustomType); - PyModule_AddObject(m, "Custom", (PyObject *) &CustomType); + if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { + Py_DECREF(&CustomType); + PY_DECREF(m); + return NULL; + } + return m; } diff --git a/Doc/includes/custom2.c b/Doc/includes/custom2.c index 6477a19dafed75..5bacab7a2a9714 100644 --- a/Doc/includes/custom2.c +++ b/Doc/includes/custom2.c @@ -128,6 +128,11 @@ PyInit_custom2(void) return NULL; Py_INCREF(&CustomType); - PyModule_AddObject(m, "Custom", (PyObject *) &CustomType); + if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { + Py_DECREF(&CustomType); + Py_DECREF(m); + return NULL; + } + return m; } diff --git a/Doc/includes/custom3.c b/Doc/includes/custom3.c index 213d0864ce1ca8..2b7a99ecf96c76 100644 --- a/Doc/includes/custom3.c +++ b/Doc/includes/custom3.c @@ -179,6 +179,11 @@ PyInit_custom3(void) return NULL; Py_INCREF(&CustomType); - PyModule_AddObject(m, "Custom", (PyObject *) &CustomType); + if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { + Py_DECREF(&CustomType); + Py_DECREF(m); + return NULL; + } + return m; } diff --git a/Doc/includes/custom4.c b/Doc/includes/custom4.c index b0b2906dbdc863..584992fc5f1a8a 100644 --- a/Doc/includes/custom4.c +++ b/Doc/includes/custom4.c @@ -193,6 +193,11 @@ PyInit_custom4(void) return NULL; Py_INCREF(&CustomType); - PyModule_AddObject(m, "Custom", (PyObject *) &CustomType); + if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { + Py_DECREF(&CustomType); + Py_DECREF(m); + return NULL; + } + return m; } diff --git a/Doc/includes/email-mime.py b/Doc/includes/email-mime.py index c610242f11f843..6af2be0b08a48d 100644 --- a/Doc/includes/email-mime.py +++ b/Doc/includes/email-mime.py @@ -14,7 +14,7 @@ # family = the list of all recipients' email addresses msg['From'] = me msg['To'] = ', '.join(family) -msg.preamble = 'Our family reunion' +msg.preamble = 'You will not see this in a MIME-aware mail reader.\n' # Open the files in binary mode. Use imghdr to figure out the # MIME subtype for each specific image. diff --git a/Doc/includes/sublist.c b/Doc/includes/sublist.c index 76ff93948cfd67..b2c26e73ebaf7e 100644 --- a/Doc/includes/sublist.c +++ b/Doc/includes/sublist.c @@ -59,6 +59,11 @@ PyInit_sublist(void) return NULL; Py_INCREF(&SubListType); - PyModule_AddObject(m, "SubList", (PyObject *) &SubListType); + if (PyModule_AddObject(m, "SubList", (PyObject *) &SubListType) < 0) { + Py_DECREF(&SubListType); + Py_DECREF(m); + return NULL; + } + return m; } diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst index dc44aa64b8e045..31e9b0bde07244 100644 --- a/Doc/installing/index.rst +++ b/Doc/installing/index.rst @@ -53,7 +53,7 @@ Key terms evolution of the standard packaging tools and the associated metadata and file format standards. They maintain a variety of tools, documentation, and issue trackers on both `GitHub `__ and - `BitBucket `__. + `Bitbucket `__. * ``distutils`` is the original build and distribution system first added to the Python standard library in 1998. While direct use of ``distutils`` is being phased out, it still laid the foundation for the current packaging diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index 26568dcbf8f532..bd653ab32bb9c4 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -106,7 +106,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. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX. .. versionadded:: 3.8 diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index b77a38ccd48577..5a61a5bf8ed90b 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -182,6 +182,10 @@ ArgumentParser objects .. versionchanged:: 3.5 *allow_abbrev* parameter was added. + .. versionchanged:: 3.8 + In previous versions, *allow_abbrev* also disabled grouping of short + flags such as ``-vv`` to mean ``-v -v``. + The following sections describe how each of these are used. @@ -806,6 +810,8 @@ how the command-line arguments should be handled. The supplied actions are: >>> parser.parse_args(["--foo", "f1", "--foo", "f2", "f3", "f4"]) Namespace(foo=['f1', 'f2', 'f3', 'f4']) + .. versionadded:: 3.8 + You may also specify an arbitrary action by passing an Action subclass or other object that implements the same interface. The recommended way to do this is to extend :class:`Action`, overriding the ``__call__`` method @@ -1098,9 +1104,8 @@ 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 object that supports the ``in`` operator can be passed as the *choices* -value, so :class:`dict` objects, :class:`set` objects, custom containers, -etc. are all supported. +Any container can be passed as the *choices* value, so :class:`list` objects, +:class:`set` objects, and custom containers are all supported. required @@ -1592,7 +1597,7 @@ Sub-commands stored; by default ``None`` and no value is stored * required_ - Whether or not a subcommand must be provided, by default - ``False``. + ``False`` (added in 3.7) * help_ - help for sub-parser group in help output, by default ``None`` @@ -1748,6 +1753,9 @@ Sub-commands >>> parser.parse_args(['2', 'frobble']) Namespace(subparser_name='2', y='frobble') + .. versionchanged:: 3.7 + New *required* keyword argument. + FileType objects ^^^^^^^^^^^^^^^^ @@ -1998,7 +2006,14 @@ Exiting methods .. method:: ArgumentParser.exit(status=0, message=None) This method terminates the program, exiting with the specified *status* - and, if given, it prints a *message* before that. + and, if given, it prints a *message* before that. The user can override + this method to handle these steps differently:: + + class ErrorCatchingArgumentParser(argparse.ArgumentParser): + def exit(self, status=0, message=None): + if status: + raise Exception(f'Exiting because of an error: {message}') + exit(status) .. method:: ArgumentParser.error(message) diff --git a/Doc/library/array.rst b/Doc/library/array.rst index 1f95dd61b9fcd7..2ae2a071262a17 100644 --- a/Doc/library/array.rst +++ b/Doc/library/array.rst @@ -36,9 +36,9 @@ defined: +-----------+--------------------+-------------------+-----------------------+-------+ | ``'L'`` | unsigned long | int | 4 | | +-----------+--------------------+-------------------+-----------------------+-------+ -| ``'q'`` | signed long long | int | 8 | \(2) | +| ``'q'`` | signed long long | int | 8 | | +-----------+--------------------+-------------------+-----------------------+-------+ -| ``'Q'`` | unsigned long long | int | 8 | \(2) | +| ``'Q'`` | unsigned long long | int | 8 | | +-----------+--------------------+-------------------+-----------------------+-------+ | ``'f'`` | float | float | 4 | | +-----------+--------------------+-------------------+-----------------------+-------+ @@ -57,13 +57,6 @@ Notes: .. deprecated-removed:: 3.3 4.0 -(2) - The ``'q'`` and ``'Q'`` type codes are available only if - the platform C compiler used to build Python supports C :c:type:`long long`, - or, on Windows, :c:type:`__int64`. - - .. versionadded:: 3.3 - The actual representation of values is determined by the machine architecture (strictly speaking, by the C implementation). The actual size can be accessed through the :attr:`itemsize` attribute. @@ -83,7 +76,7 @@ The module defines the following type: to add initial items to the array. Otherwise, the iterable initializer is passed to the :meth:`extend` method. - .. audit-event:: array.__new__ "typecode initializer" + .. audit-event:: array.__new__ typecode,initializer array.array .. data:: typecodes diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 1884bea80e8047..92bf8912eb53dd 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -126,7 +126,7 @@ The abstract grammar is currently defined as follows: Apart from the node classes, the :mod:`ast` module defines these utility functions and classes for traversing abstract syntax trees: -.. function:: parse(source, filename='', mode='exec', *, type_comments=False, feature_version=-1) +.. function:: parse(source, filename='', mode='exec', *, type_comments=False, feature_version=None) Parse the source into an AST node. Equivalent to ``compile(source, filename, mode, ast.PyCF_ONLY_AST)``. @@ -145,11 +145,12 @@ and classes for traversing abstract syntax trees: modified to correspond to :pep:`484` "signature type comments", e.g. ``(str, int) -> List[str]``. - Also, setting ``feature_version`` to the minor version of an - earlier Python 3 version will attempt to parse using that version's - grammar. For example, setting ``feature_version=4`` will allow - the use of ``async`` and ``await`` as variable names. The lowest - supported value is 4; the highest is ``sys.version_info[1]``. + Also, setting ``feature_version`` to a tuple ``(major, minor)`` + will attempt to parse using that Python version's grammar. + Currently ``major`` must equal to ``3``. For example, setting + ``feature_version=(3, 4)`` will allow the use of ``async`` and + ``await`` as variable names. The lowest supported version is + ``(3, 4)``; the highest is ``sys.version_info[0:2]``. .. warning:: It is possible to crash the Python interpreter with a @@ -274,6 +275,13 @@ and classes for traversing abstract syntax trees: during traversal. For this a special visitor exists (:class:`NodeTransformer`) that allows modifications. + .. deprecated:: 3.8 + + Methods :meth:`visit_Num`, :meth:`visit_Str`, :meth:`visit_Bytes`, + :meth:`visit_NameConstant` and :meth:`visit_Ellipsis` are deprecated + now and will not be called in future Python versions. Add the + :meth:`visit_Constant` method to handle all constant nodes. + .. class:: NodeTransformer() @@ -314,11 +322,12 @@ and classes for traversing abstract syntax trees: .. function:: dump(node, annotate_fields=True, include_attributes=False) Return a formatted dump of the tree in *node*. This is mainly useful for - debugging purposes. The returned string will show the names and the values - for fields. This makes the code impossible to evaluate, so if evaluation is - wanted *annotate_fields* must be set to ``False``. Attributes such as line + debugging purposes. If *annotate_fields* is true (by default), + the returned string will show the names and the values for fields. + If *annotate_fields* is false, the result string will be more compact by + omitting unambiguous field names. Attributes such as line numbers and column offsets are not dumped by default. If this is wanted, - *include_attributes* can be set to ``True``. + *include_attributes* can be set to true. .. seealso:: diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index b7288036192979..101e7817a95e98 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -119,7 +119,7 @@ all concurrent asyncio Tasks and IO operations would be delayed by 1 second. An executor can be used to run a task in a different thread or even in -a different process to avoid blocking block the OS thread with the +a different process to avoid blocking the OS thread with the event loop. See the :meth:`loop.run_in_executor` method for more details. diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 8673f84e96382e..1f4f0b6e75b9e7 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -5,6 +5,10 @@ Event Loop ========== +**Source code:** :source:`Lib/asyncio/events.py`, +:source:`Lib/asyncio/base_events.py` + +------------------------------------ .. rubric:: Preface @@ -1454,7 +1458,7 @@ asyncio ships with two different event loop implementations: :class:`SelectorEventLoop` and :class:`ProactorEventLoop`. By default asyncio is configured to use :class:`SelectorEventLoop` -on all platforms. +on Unix and :class:`ProactorEventLoop` on Windows. .. class:: SelectorEventLoop diff --git a/Doc/library/asyncio-exceptions.rst b/Doc/library/asyncio-exceptions.rst index e49577a203e8fb..7166d5c4bd88f9 100644 --- a/Doc/library/asyncio-exceptions.rst +++ b/Doc/library/asyncio-exceptions.rst @@ -7,6 +7,9 @@ Exceptions ========== +**Source code:** :source:`Lib/asyncio/exceptions.py` + +---------------------------------------------------- .. exception:: TimeoutError @@ -25,26 +28,9 @@ Exceptions when asyncio Tasks are cancelled. In almost all situations the exception must be re-raised. - .. important:: - - This exception is a subclass of :exc:`Exception`, so it can be - accidentally suppressed by an overly broad ``try..except`` block:: - - try: - await operation - except Exception: - # The cancellation is broken because the *except* block - # suppresses the CancelledError exception. - log.log('an error has occurred') - - Instead, the following pattern should be used:: + .. versionchanged:: 3.8 - try: - await operation - except asyncio.CancelledError: - raise - except Exception: - log.log('an error has occurred') + :exc:`CancelledError` is now a subclass of :class:`BaseException`. .. exception:: InvalidStateError diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst index 6e6e0137c1bdda..832d58119b7b07 100644 --- a/Doc/library/asyncio-future.rst +++ b/Doc/library/asyncio-future.rst @@ -7,6 +7,11 @@ Futures ======= +**Source code:** :source:`Lib/asyncio/futures.py`, +:source:`Lib/asyncio/base_futures.py` + +------------------------------------- + *Future* objects are used to bridge **low-level callback-based code** with high-level async/await code. @@ -35,7 +40,9 @@ Future Functions is used for the test.) * a :class:`Task` object wrapping *obj*, if *obj* is a - coroutine (:func:`iscoroutine` is used for the test.) + coroutine (:func:`iscoroutine` is used for the test); + in this case the coroutine will be scheduled by + ``ensure_future()``. * a :class:`Task` object that would await on *obj*, if *obj* is an awaitable (:func:`inspect.isawaitable` is used for the test.) diff --git a/Doc/library/asyncio-platforms.rst b/Doc/library/asyncio-platforms.rst index 7e4a70f91c6ed5..390ee1969d096f 100644 --- a/Doc/library/asyncio-platforms.rst +++ b/Doc/library/asyncio-platforms.rst @@ -23,6 +23,12 @@ All Platforms Windows ======= +**Source code:** :source:`Lib/asyncio/proactor_events.py`, +:source:`Lib/asyncio/windows_events.py`, +:source:`Lib/asyncio/windows_utils.py` + +-------------------------------------- + .. versionchanged:: 3.8 On Windows, :class:`ProactorEventLoop` is now the default event loop. diff --git a/Doc/library/asyncio-policy.rst b/Doc/library/asyncio-policy.rst index 6212df85dbc10a..aa8f8f13eae021 100644 --- a/Doc/library/asyncio-policy.rst +++ b/Doc/library/asyncio-policy.rst @@ -117,6 +117,7 @@ asyncio ships with the following built-in policies: .. availability:: Windows. +.. _asyncio-watchers: Process Watchers ================ @@ -129,10 +130,11 @@ In asyncio, child processes are created with :func:`create_subprocess_exec` and :meth:`loop.subprocess_exec` functions. -asyncio defines the :class:`AbstractChildWatcher` abstract base class, -which child watchers should implement, and has two different -implementations: :class:`SafeChildWatcher` (configured to be used -by default) and :class:`FastChildWatcher`. +asyncio defines the :class:`AbstractChildWatcher` abstract base class, which child +watchers should implement, and has four different implementations: +:class:`ThreadedChildWatcher` (configured to be used by default), +:class:`MultiLoopChildWatcher`, :class:`SafeChildWatcher`, and +:class:`FastChildWatcher`. See also the :ref:`Subprocess and Threads ` section. @@ -184,6 +186,15 @@ implementation used by the asyncio event loop: Note: loop may be ``None``. + .. method:: is_active() + + Return ``True`` if the watcher is ready to use. + + Spawning a subprocess with *inactive* current child watcher raises + :exc:`RuntimeError`. + + .. versionadded:: 3.8 + .. method:: close() Close the watcher. @@ -191,16 +202,48 @@ implementation used by the asyncio event loop: This method has to be called to ensure that underlying resources are cleaned-up. -.. class:: SafeChildWatcher +.. class:: ThreadedChildWatcher + + This implementation starts a new waiting thread for every subprocess spawn. + + It works reliably even when the asyncio event loop is run in a non-main OS thread. + + There is no noticeable overhead when handling a big number of children (*O(1)* each + time a child terminates), but stating a thread per process requires extra memory. + + This watcher is used by default. + + .. versionadded:: 3.8 - This implementation avoids disrupting other code spawning processes +.. class:: MultiLoopChildWatcher + + This implementation registers a :py:data:`SIGCHLD` signal handler on + instantiation. That can break third-party code that installs a custom handler for + `SIGCHLD`. signal). + + The watcher avoids disrupting other code spawning processes by polling every process explicitly on a :py:data:`SIGCHLD` signal. - This is a safe solution but it has a significant overhead when + There is no limitation for running subprocesses from different threads once the + watcher is installed. + + The solution is safe but it has a significant overhead when handling a big number of processes (*O(n)* each time a :py:data:`SIGCHLD` is received). - asyncio uses this safe implementation by default. + .. versionadded:: 3.8 + +.. class:: SafeChildWatcher + + This implementation uses active event loop from the main thread to handle + :py:data:`SIGCHLD` signal. If the main thread has no running event loop another + thread cannot spawn a subprocess (:exc:`RuntimeError` is raised). + + The watcher avoids disrupting other code spawning processes + by polling every process explicitly on a :py:data:`SIGCHLD` signal. + + 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. .. class:: FastChildWatcher @@ -211,6 +254,9 @@ implementation used by the asyncio event loop: There is no noticeable overhead when handling a big number of children (*O(1)* each time a child terminates). + This solution requires a running event loop in the main thread to work, as + :class:`SafeChildWatcher`. + Custom Policies =============== diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst index f08738dd62bb5c..ffac9018127c66 100644 --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -69,6 +69,10 @@ This documentation page contains the following sections: Transports ========== +**Source code:** :source:`Lib/asyncio/transports.py` + +---------------------------------------------------- + Transports are classes provided by :mod:`asyncio` in order to abstract various kinds of communication channels. @@ -431,6 +435,10 @@ Subprocess Transports Protocols ========= +**Source code:** :source:`Lib/asyncio/protocols.py` + +--------------------------------------------------- + asyncio provides a set of abstract base classes that should be used to implement network protocols. Those classes are meant to be used together with :ref:`transports `. @@ -767,9 +775,8 @@ data, and waits until the connection is closed:: class EchoClientProtocol(asyncio.Protocol): - def __init__(self, message, on_con_lost, loop): + def __init__(self, message, on_con_lost): self.message = message - self.loop = loop self.on_con_lost = on_con_lost def connection_made(self, transport): @@ -793,7 +800,7 @@ data, and waits until the connection is closed:: message = 'Hello World!' transport, protocol = await loop.create_connection( - lambda: EchoClientProtocol(message, on_con_lost, loop), + lambda: EchoClientProtocol(message, on_con_lost), '127.0.0.1', 8888) # Wait until the protocol signals that the connection @@ -869,11 +876,10 @@ method, sends data and closes the transport when it receives the answer:: class EchoClientProtocol: - def __init__(self, message, loop): + def __init__(self, message, on_con_lost): self.message = message - self.loop = loop + self.on_con_lost = on_con_lost self.transport = None - self.on_con_lost = loop.create_future() def connection_made(self, transport): self.transport = transport @@ -899,13 +905,15 @@ method, sends data and closes the transport when it receives the answer:: # low-level APIs. loop = asyncio.get_running_loop() + on_con_lost = loop.create_future() message = "Hello World!" + transport, protocol = await loop.create_datagram_endpoint( - lambda: EchoClientProtocol(message, loop), + lambda: EchoClientProtocol(message, on_con_lost), remote_addr=('127.0.0.1', 9999)) try: - await protocol.on_con_lost + await on_con_lost finally: transport.close() @@ -927,9 +935,9 @@ Wait until a socket receives data using the class MyProtocol(asyncio.Protocol): - def __init__(self, loop): + def __init__(self, on_con_lost): self.transport = None - self.on_con_lost = loop.create_future() + self.on_con_lost = on_con_lost def connection_made(self, transport): self.transport = transport @@ -950,13 +958,14 @@ Wait until a socket receives data using the # Get a reference to the event loop as we plan to use # low-level APIs. loop = asyncio.get_running_loop() + on_con_lost = loop.create_future() # Create a pair of connected sockets rsock, wsock = socket.socketpair() # Register the socket to wait for data. transport, protocol = await loop.create_connection( - lambda: MyProtocol(loop), sock=rsock) + lambda: MyProtocol(on_con_lost), sock=rsock) # Simulate the reception of data from the network. loop.call_soon(wsock.send, 'abc'.encode()) diff --git a/Doc/library/asyncio-queue.rst b/Doc/library/asyncio-queue.rst index 7be1023c80cc66..524560b691d720 100644 --- a/Doc/library/asyncio-queue.rst +++ b/Doc/library/asyncio-queue.rst @@ -6,6 +6,10 @@ Queues ====== +**Source code:** :source:`Lib/asyncio/queues.py` + +------------------------------------------------ + asyncio queues are designed to be similar to classes of the :mod:`queue` module. Although asyncio queues are not thread-safe, they are designed to be used specifically in async/await code. @@ -32,6 +36,10 @@ Queue the queue is always known and can be returned by calling the :meth:`qsize` method. + .. deprecated-removed:: 3.8 3.10 + The *loop* parameter. + + This class is :ref:`not thread safe `. .. attribute:: maxsize diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index 28ca5d5f339692..bb899714a0ec06 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -6,6 +6,10 @@ Streams ======= +**Source code:** :source:`Lib/asyncio/streams.py` + +------------------------------------------------- + Streams are high-level async/await-ready primitives to work with network connections. Streams allow sending and receiving data without using callbacks or low-level protocols and transports. @@ -22,13 +26,15 @@ streams:: '127.0.0.1', 8888) print(f'Send: {message!r}') - await writer.write(message.encode()) + writer.write(message.encode()) + await writer.drain() data = await reader.read(100) print(f'Received: {data.decode()!r}') print('Close the connection') - await writer.close() + writer.close() + await writer.wait_closed() asyncio.run(tcp_echo_client('Hello World!')) @@ -67,10 +73,6 @@ and work with streams: The *ssl_handshake_timeout* parameter. - .. deprecated-removed:: 3.8 3.10 - - `open_connection()` is deprecated in favor of `connect()`. - .. coroutinefunction:: start_server(client_connected_cb, host=None, \ port=None, \*, loop=None, limit=None, \ family=socket.AF_UNSPEC, \ @@ -104,10 +106,6 @@ and work with streams: The *ssl_handshake_timeout* and *start_serving* parameters. - .. deprecated-removed:: 3.8 3.10 - - `start_server()` is deprecated if favor of `StreamServer()` - .. rubric:: Unix Sockets @@ -132,10 +130,6 @@ and work with streams: The *path* parameter can now be a :term:`path-like object` - .. deprecated-removed:: 3.8 3.10 - - `open_unix_connection()` is deprecated if favor of `connect_unix()`. - .. coroutinefunction:: start_unix_server(client_connected_cb, path=None, \ \*, loop=None, limit=None, sock=None, \ @@ -158,13 +152,6 @@ and work with streams: The *path* parameter can now be a :term:`path-like object`. - .. deprecated-removed:: 3.8 3.10 - - `start_unix_server()` is deprecated in favor of `UnixStreamServer()`. - - ---------- - StreamReader ============ @@ -248,22 +235,11 @@ StreamWriter If that fails, the data is queued in an internal write buffer until it can be sent. - Starting with Python 3.8, it is possible to directly await on the `write()` - method:: - - await stream.write(data) - - The ``await`` pauses the current coroutine until the data is written to the - socket. - - Below is an equivalent code that works with Python <= 3.7:: + The method should be used along with the ``drain()`` method:: stream.write(data) await stream.drain() - .. versionchanged:: 3.8 - Support ``await stream.write(...)`` syntax. - .. method:: writelines(data) The method writes a list (or any iterable) of bytes to the underlying socket @@ -271,42 +247,20 @@ StreamWriter If that fails, the data is queued in an internal write buffer until it can be sent. - Starting with Python 3.8, it is possible to directly await on the `write()` - method:: - - await stream.writelines(lines) - - The ``await`` pauses the current coroutine until the data is written to the - socket. - - Below is an equivalent code that works with Python <= 3.7:: + The method should be used along with the ``drain()`` method:: stream.writelines(lines) await stream.drain() - .. versionchanged:: 3.8 - Support ``await stream.writelines()`` syntax. - .. method:: close() The method closes the stream and the underlying socket. - Starting with Python 3.8, it is possible to directly await on the `close()` - method:: - - await stream.close() - - The ``await`` pauses the current coroutine until the stream and the underlying - socket are closed (and SSL shutdown is performed for a secure connection). - - Below is an equivalent code that works with Python <= 3.7:: + The method should be used along with the ``wait_closed()`` method:: stream.close() await stream.wait_closed() - .. versionchanged:: 3.8 - Support ``await stream.close()`` syntax. - .. method:: can_write_eof() Return *True* if the underlying transport supports diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst index 00dc66c48b2189..1d87d2f8005ec6 100644 --- a/Doc/library/asyncio-subprocess.rst +++ b/Doc/library/asyncio-subprocess.rst @@ -6,6 +6,11 @@ Subprocesses ============ +**Source code:** :source:`Lib/asyncio/subprocess.py`, +:source:`Lib/asyncio/base_subprocess.py` + +---------------------------------------- + This section describes high-level async/await asyncio APIs to create and manage subprocesses. @@ -71,6 +76,10 @@ Creating Subprocesses See the documentation of :meth:`loop.subprocess_exec` for other parameters. + .. deprecated-removed:: 3.8 3.10 + + The *loop* parameter. + .. coroutinefunction:: create_subprocess_shell(cmd, stdin=None, \ stdout=None, stderr=None, loop=None, \ limit=None, \*\*kwds) @@ -95,6 +104,10 @@ 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. + .. note:: The default asyncio event loop implementation on **Windows** does not @@ -293,18 +306,26 @@ their completion. Subprocess and Threads ---------------------- -Standard asyncio event loop supports running subprocesses from -different threads, but there are limitations: +Standard asyncio event loop supports running subprocesses from different threads by +default. + +On Windows subprocesses are provided by :class:`ProactorEventLoop` only (default), +:class:`SelectorEventLoop` has no subprocess support. + +On UNIX *child watchers* are used for subprocess finish waiting, see +:ref:`asyncio-watchers` for more info. + + +.. versionchanged:: 3.8 -* An event loop must run in the main thread. + UNIX switched to use :class:`ThreadedChildWatcher` for spawning subprocesses from + different threads without any limitation. -* The child watcher must be instantiated in the main thread - before executing subprocesses from other threads. Call the - :func:`get_child_watcher` function in the main thread to instantiate - the child watcher. + Spawning a subprocess with *inactive* current child watcher raises + :exc:`RuntimeError`. -Note that alternative event loop implementations might not share -the above limitations; please refer to their documentation. +Note that alternative event loop implementations might have own limitations; +please refer to their documentation. .. seealso:: diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst index 79f6b02d85e2e5..f080b03bc7c51c 100644 --- a/Doc/library/asyncio-sync.rst +++ b/Doc/library/asyncio-sync.rst @@ -6,6 +6,10 @@ Synchronization Primitives ========================== +**Source code:** :source:`Lib/asyncio/locks.py` + +----------------------------------------------- + asyncio synchronization primitives are designed to be similar to those of the :mod:`threading` module with two important caveats: @@ -59,6 +63,9 @@ Lock finally: lock.release() + .. deprecated-removed:: 3.8 3.10 + The *loop* parameter. + .. coroutinemethod:: acquire() Acquire the lock. @@ -101,6 +108,10 @@ Event :meth:`clear` method. The :meth:`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. + .. _asyncio_example_sync_event: Example:: @@ -173,6 +184,10 @@ Condition ``None``. In the latter case a new Lock object is created automatically. + + .. deprecated-removed:: 3.8 3.10 + The *loop* parameter. + The preferred way to use a Condition is an :keyword:`async with` statement:: @@ -269,6 +284,10 @@ 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. + The preferred way to use a Semaphore is an :keyword:`async with` statement:: @@ -322,6 +341,9 @@ BoundedSemaphore increases the internal counter above the initial *value*. + .. deprecated-removed:: 3.8 3.10 + The *loop* parameter. + --------- diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 1fcdcb985d8842..1a23661fc772e5 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -18,9 +18,9 @@ and Tasks. Coroutines ========== -Coroutines declared with 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, +: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, and then prints "world":: >>> import asyncio @@ -212,6 +212,8 @@ 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 and *finalizing asynchronous generators*. @@ -225,11 +227,21 @@ Running an asyncio Program 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 - **Important:** this function has been added to asyncio in - Python 3.7 on a :term:`provisional basis `. + .. note:: + The source code for ``asyncio.run()`` can be found in + :source:`Lib/asyncio/runners.py`. + Creating Tasks ============== @@ -334,6 +346,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. + .. _asyncio_example_gather: Example:: @@ -411,6 +426,9 @@ Shielding From Cancellation except CancelledError: res = None + .. deprecated-removed:: 3.8 3.10 + The *loop* parameter. + Timeouts ======== @@ -478,22 +496,12 @@ Waiting Primitives set concurrently and block until the condition specified by *return_when*. - .. 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 `. - Returns two sets of Tasks/Futures: ``(done, pending)``. Usage:: done, pending = await asyncio.wait(aws) - .. deprecated-removed:: 3.8 3.10 - The *loop* parameter. - *timeout* (a float or int), if specified, can be used to control the maximum number of seconds to wait before returning. @@ -525,6 +533,17 @@ 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. + .. _asyncio_example_wait_coroutine: .. note:: @@ -568,6 +587,9 @@ Waiting Primitives Raises :exc:`asyncio.TimeoutError` if the timeout occurs before all Futures are done. + .. deprecated-removed:: 3.8 3.10 + The *loop* parameter. + Example:: for f in as_completed(aws): @@ -694,6 +716,9 @@ Task Object .. versionchanged:: 3.8 Added the ``name`` parameter. + .. deprecated-removed:: 3.8 3.10 + The *loop* parameter. + .. method:: cancel() Request the Task to be cancelled. diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst index 6990adb21e3603..94a853259d3483 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -4,7 +4,7 @@ .. module:: asyncio :synopsis: Asynchronous I/O. --------------- +------------------------------- .. sidebar:: Hello World! @@ -91,3 +91,6 @@ Additionally, there are **low-level** APIs for asyncio-api-index.rst asyncio-llapi-index.rst asyncio-dev.rst + +.. note:: + The source code for asyncio can be found in :source:`Lib/asyncio/`. diff --git a/Doc/library/audit_events.rst b/Doc/library/audit_events.rst new file mode 100644 index 00000000000000..c23b9c618323de --- /dev/null +++ b/Doc/library/audit_events.rst @@ -0,0 +1,21 @@ +.. _audit-events: + +.. index:: single: audit events + +Audit events table +================== + +This table contains all events raised by :func:`sys.audit` or +:c:func:`PySys_Audit` calls throughout the CPython runtime and the +standard library. + +See :func:`sys.addaudithook` and :c:func:`PySys_AddAuditHook` for +information on handling these events. + +.. impl-detail:: + + This table is generated from the CPython documentation, and may not + represent events raised by other implementations. See your runtime + specific documentation for actual events raised. + +.. audit-event-table:: diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 2e9314e0fab793..992672e806f336 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -292,7 +292,7 @@ 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 +accepting the *errors* string argument. The following string values are defined and implemented by all standard Python codecs: .. tabularcolumns:: |l|L| @@ -301,11 +301,11 @@ defined and implemented by all standard Python codecs: | Value | Meaning | +=========================+===============================================+ | ``'strict'`` | Raise :exc:`UnicodeError` (or a subclass); | -| | this is the default. Implemented in | +| | this is the default. Implemented in | | | :func:`strict_errors`. | +-------------------------+-----------------------------------------------+ | ``'ignore'`` | Ignore the malformed data and continue | -| | without further notice. Implemented in | +| | without further notice. Implemented in | | | :func:`ignore_errors`. | +-------------------------+-----------------------------------------------+ @@ -327,11 +327,11 @@ The following error handlers are only applicable to | | marker; Python will use the official | | | ``U+FFFD`` REPLACEMENT CHARACTER for the | | | built-in codecs on decoding, and '?' on | -| | encoding. Implemented in | +| | encoding. Implemented in | | | :func:`replace_errors`. | +-------------------------+-----------------------------------------------+ | ``'xmlcharrefreplace'`` | Replace with the appropriate XML character | -| | reference (only for encoding). Implemented | +| | reference (only for encoding). Implemented | | | in :func:`xmlcharrefreplace_errors`. | +-------------------------+-----------------------------------------------+ | ``'backslashreplace'`` | Replace with backslashed escape sequences. | @@ -339,15 +339,15 @@ The following error handlers are only applicable to | | :func:`backslashreplace_errors`. | +-------------------------+-----------------------------------------------+ | ``'namereplace'`` | Replace with ``\N{...}`` escape sequences | -| | (only for encoding). Implemented in | +| | (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 | +| | ``U+DCFF``. This code will then be turned | | | back into the same byte when the | | | ``'surrogateescape'`` error handler is used | -| | when encoding the data. (See :pep:`383` for | +| | when encoding the data. (See :pep:`383` for | | | more.) | +-------------------------+-----------------------------------------------+ @@ -357,7 +357,7 @@ 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-16-be, utf-16-le, | codes. These codecs normally treat the | | | utf-32-be, utf-32-le | presence of surrogates as an error. | +-------------------+------------------------+-------------------------------------------+ @@ -388,9 +388,9 @@ handler: error handler must either raise this or a different exception, or return a tuple with a replacement for the unencodable part of the input and a position where encoding should continue. The replacement may be either :class:`str` or - :class:`bytes`. If the replacement is bytes, the encoder will simply copy + :class:`bytes`. If the replacement is bytes, the encoder will simply copy them into the output buffer. If the replacement is a string, the encoder will - encode the replacement. Encoding continues on original input at the + encode the replacement. Encoding continues on original input at the specified position. Negative position values will be treated as being relative to the end of the input string. If the resulting position is out of bound an :exc:`IndexError` will be raised. @@ -484,7 +484,7 @@ function interfaces of the stateless encoder and decoder: .. method:: Codec.decode(input[, errors]) Decodes the object *input* and returns a tuple (output object, length - consumed). For instance, for a :term:`text encoding`, decoding converts + consumed). For instance, for a :term:`text encoding`, decoding converts a bytes object encoded using a particular character set encoding to a string object. @@ -568,7 +568,7 @@ define in order to be compatible with the Python codec registry. implementation should make sure that ``0`` is the most common state. (States that are more complicated than integers can be converted into an integer by marshaling/pickling the state and encoding the bytes - of the resulting string into an integer). + of the resulting string into an integer.) .. method:: setstate(state) @@ -751,7 +751,7 @@ compatible with the Python codec registry. number of encoded bytes or code points to read for decoding. The decoder can modify this setting as appropriate. The default value -1 indicates to read and decode as much as - possible. This parameter is intended to + possible. This parameter is intended to prevent having to decode huge files in one step. The *firstline* flag indicates that @@ -780,8 +780,8 @@ compatible with the Python codec registry. Read all lines available on the input stream and return them as a list of lines. - Line-endings are implemented using the codec's decoder method and are - included in the list entries if *keepends* is true. + Line-endings are implemented using the codec's :meth:`decode` method and + are included in the list entries if *keepends* is true. *sizehint*, if given, is passed as the *size* argument to the stream's :meth:`read` method. @@ -791,7 +791,7 @@ compatible with the Python codec registry. Resets the codec buffers used for keeping state. - Note that no stream repositioning should take place. This method is + Note that no stream repositioning should take place. This method is primarily intended to be able to recover from decoding errors. @@ -841,7 +841,7 @@ The design is such that one can use the factory functions returned by the code calling :meth:`read` and :meth:`write`, while *Reader* and *Writer* work on the backend — the data in *stream*. - You can use these objects to do transparent transcodings from e.g. Latin-1 + You can use these objects to do transparent transcodings, e.g., from Latin-1 to UTF-8 and back. The *stream* argument must be a file-like object. @@ -866,10 +866,10 @@ Encodings and Unicode --------------------- Strings are stored internally as sequences of code points in -range ``0x0``--``0x10FFFF``. (See :pep:`393` for +range ``0x0``--``0x10FFFF``. (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 +and how these arrays are stored as bytes become an issue. As with other codecs, serialising 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 serialisation codecs, which are @@ -964,7 +964,7 @@ to determine the byte order used for generating the byte sequence, but as a signature that helps in guessing the encoding. On encoding the utf-8-sig codec will write ``0xef``, ``0xbb``, ``0xbf`` as the first three bytes to the file. On decoding ``utf-8-sig`` will skip those three bytes if they appear as the first -three bytes in the file. In UTF-8, the use of the BOM is discouraged and +three bytes in the file. In UTF-8, the use of the BOM is discouraged and should generally be avoided. @@ -984,7 +984,7 @@ e.g. ``'utf-8'`` is a valid alias for the ``'utf_8'`` codec. .. impl-detail:: Some common encodings can bypass the codecs lookup machinery to - improve performance. These optimization opportunities are only + improve performance. These optimization opportunities are only recognized by CPython for a limited set of (case insensitive) aliases: utf-8, utf8, latin-1, latin1, iso-8859-1, iso8859-1, mbcs (Windows only), ascii, us-ascii, utf-16, utf16, utf-32, utf32, and @@ -1145,7 +1145,7 @@ particular, the following variants typically exist: | iso2022_kr | csiso2022kr, iso2022kr, | Korean | | | iso-2022-kr | | +-----------------+--------------------------------+--------------------------------+ -| latin_1 | iso-8859-1, iso8859-1, 8859, | West Europe | +| latin_1 | iso-8859-1, iso8859-1, 8859, | Western Europe | | | cp819, latin, latin1, L1 | | +-----------------+--------------------------------+--------------------------------+ | iso8859_2 | iso-8859-2, latin2, L2 | Central and Eastern Europe | @@ -1249,11 +1249,11 @@ Python Specific Encodings ------------------------- A number of predefined codecs are specific to Python, so their codec names have -no meaning outside Python. These are listed in the tables below based on the +no meaning outside Python. These are listed in the tables below based on the expected input and output types (note that while text encodings are the most common use case for codecs, the underlying codec infrastructure supports -arbitrary data transforms rather than just text encodings). For asymmetric -codecs, the stated purpose describes the encoding direction. +arbitrary data transforms rather than just text encodings). For asymmetric +codecs, the stated meaning describes the encoding direction. Text Encodings ^^^^^^^^^^^^^^ @@ -1265,27 +1265,27 @@ encodings. .. tabularcolumns:: |l|p{0.3\linewidth}|p{0.3\linewidth}| +--------------------+---------+---------------------------+ -| Codec | Aliases | Purpose | +| Codec | Aliases | Meaning | +====================+=========+===========================+ -| idna | | Implements :rfc:`3490`, | +| idna | | Implement :rfc:`3490`, | | | | see also | | | | :mod:`encodings.idna`. | | | | Only ``errors='strict'`` | | | | is supported. | +--------------------+---------+---------------------------+ -| mbcs | ansi, | Windows only: Encode | +| mbcs | ansi, | Windows only: Encode the | | | dbcs | operand according to the | -| | | ANSI codepage (CP_ACP) | +| | | ANSI codepage (CP_ACP). | +--------------------+---------+---------------------------+ -| oem | | Windows only: Encode | +| oem | | Windows only: Encode the | | | | operand according to the | -| | | OEM codepage (CP_OEMCP) | +| | | OEM codepage (CP_OEMCP). | | | | | | | | .. versionadded:: 3.6 | +--------------------+---------+---------------------------+ -| palmos | | Encoding of PalmOS 3.5 | +| palmos | | Encoding of PalmOS 3.5. | +--------------------+---------+---------------------------+ -| punycode | | Implements :rfc:`3492`. | +| punycode | | Implement :rfc:`3492`. | | | | Stateful codecs are not | | | | supported. | +--------------------+---------+---------------------------+ @@ -1308,8 +1308,8 @@ encodings. | | | literal in ASCII-encoded | | | | Python source code, | | | | except that quotes are | -| | | not escaped. Decodes from | -| | | Latin-1 source code. | +| | | not escaped. Decode | +| | | from Latin-1 source code. | | | | Beware that Python source | | | | code actually uses UTF-8 | | | | by default. | @@ -1325,19 +1325,19 @@ Binary Transforms ^^^^^^^^^^^^^^^^^ The following codecs provide binary transforms: :term:`bytes-like object` -to :class:`bytes` mappings. They are not supported by :meth:`bytes.decode` +to :class:`bytes` mappings. They are not supported by :meth:`bytes.decode` (which only produces :class:`str` output). .. tabularcolumns:: |l|L|L|L| +----------------------+------------------+------------------------------+------------------------------+ -| Codec | Aliases | Purpose | Encoder / decoder | +| Codec | Aliases | Meaning | Encoder / decoder | +======================+==================+==============================+==============================+ -| base64_codec [#b64]_ | base64, base_64 | Convert operand to multiline | :meth:`base64.encodebytes` / | -| | | MIME base64 (the result | :meth:`base64.decodebytes` | -| | | always includes a trailing | | -| | | ``'\n'``) | | +| base64_codec [#b64]_ | base64, base_64 | Convert the operand to | :meth:`base64.encodebytes` / | +| | | multiline MIME base64 (the | :meth:`base64.decodebytes` | +| | | result always includes a | | +| | | trailing ``'\n'``). | | | | | | | | | | .. versionchanged:: 3.4 | | | | | accepts any | | @@ -1345,23 +1345,23 @@ to :class:`bytes` mappings. They are not supported by :meth:`bytes.decode` | | | as input for encoding and | | | | | decoding | | +----------------------+------------------+------------------------------+------------------------------+ -| bz2_codec | bz2 | Compress the operand | :meth:`bz2.compress` / | -| | | using bz2 | :meth:`bz2.decompress` | +| bz2_codec | bz2 | Compress the operand using | :meth:`bz2.compress` / | +| | | bz2. | :meth:`bz2.decompress` | +----------------------+------------------+------------------------------+------------------------------+ -| hex_codec | hex | Convert operand to | :meth:`binascii.b2a_hex` / | +| hex_codec | hex | Convert the operand to | :meth:`binascii.b2a_hex` / | | | | hexadecimal | :meth:`binascii.a2b_hex` | | | | representation, with two | | -| | | digits per byte | | +| | | digits per byte. | | +----------------------+------------------+------------------------------+------------------------------+ -| quopri_codec | quopri, | Convert operand to MIME | :meth:`quopri.encode` with | -| | quotedprintable, | quoted printable | ``quotetabs=True`` / | +| quopri_codec | quopri, | Convert the operand to MIME | :meth:`quopri.encode` with | +| | quotedprintable, | quoted printable. | ``quotetabs=True`` / | | | quoted_printable | | :meth:`quopri.decode` | +----------------------+------------------+------------------------------+------------------------------+ | uu_codec | uu | Convert the operand using | :meth:`uu.encode` / | -| | | uuencode | :meth:`uu.decode` | +| | | uuencode. | :meth:`uu.decode` | +----------------------+------------------+------------------------------+------------------------------+ -| zlib_codec | zip, zlib | Compress the operand | :meth:`zlib.compress` / | -| | | using gzip | :meth:`zlib.decompress` | +| zlib_codec | zip, zlib | Compress the operand using | :meth:`zlib.compress` / | +| | | gzip. | :meth:`zlib.decompress` | +----------------------+------------------+------------------------------+------------------------------+ .. [#b64] In addition to :term:`bytes-like objects `, @@ -1381,16 +1381,17 @@ Text Transforms ^^^^^^^^^^^^^^^ The following codec provides a text transform: a :class:`str` to :class:`str` -mapping. It is not supported by :meth:`str.encode` (which only produces +mapping. It is not supported by :meth:`str.encode` (which only produces :class:`bytes` output). .. tabularcolumns:: |l|l|L| +--------------------+---------+---------------------------+ -| Codec | Aliases | Purpose | +| Codec | Aliases | Meaning | +====================+=========+===========================+ -| rot_13 | rot13 | Returns the Caesar-cypher | -| | | encryption of the operand | +| rot_13 | rot13 | Return the Caesar-cypher | +| | | encryption of the | +| | | operand. | +--------------------+---------+---------------------------+ .. versionadded:: 3.2 @@ -1428,7 +1429,7 @@ conversion between Unicode and ACE, separating an input string into labels based on the separator characters defined in :rfc:`section 3.1 of RFC 3490 <3490#section-3.1>` and converting each label to ACE as required, and conversely separating an input byte string into labels based on the ``.`` separator and converting any ACE -labels found into unicode. Furthermore, the :mod:`socket` module +labels found into unicode. Furthermore, the :mod:`socket` module transparently converts Unicode host names to ACE, so that applications need not be concerned about converting host names themselves when they pass them to the socket module. On top of that, modules that have host names as function @@ -1437,7 +1438,7 @@ names (:mod:`http.client` then also transparently sends an IDNA hostname in the :mailheader:`Host` field if it sends that field at all). When receiving host names from the wire (such as in reverse name lookup), no -automatic conversion to Unicode is performed: Applications wishing to present +automatic conversion to Unicode is performed: applications wishing to present such host names to the user should decode them to Unicode. The module :mod:`encodings.idna` also implements the nameprep procedure, which @@ -1469,7 +1470,7 @@ functions can be used directly if desired. .. module:: encodings.mbcs :synopsis: Windows ANSI codepage -Encode operand according to the ANSI codepage (CP_ACP). +This module implements the ANSI codepage (CP_ACP). .. availability:: Windows only. @@ -1488,7 +1489,7 @@ Encode operand according to the ANSI codepage (CP_ACP). :synopsis: UTF-8 codec with BOM signature .. moduleauthor:: Walter Dörwald -This module implements a variant of the UTF-8 codec: On encoding a UTF-8 encoded +This module implements a variant of the UTF-8 codec. On encoding, a UTF-8 encoded BOM will be prepended to the UTF-8 encoded bytes. For the stateful encoder this -is only done once (on the first write to the byte stream). For decoding an +is only done once (on the first write to the byte stream). On decoding, an optional UTF-8 encoded BOM at the start of the data will be skipped. diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst index bb5000a0736ccc..9ce5ca819c68a1 100644 --- a/Doc/library/compileall.rst +++ b/Doc/library/compileall.rst @@ -120,7 +120,7 @@ runtime. Public functions ---------------- -.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1, invalidation_mode=py_compile.PycInvalidationMode.TIMESTAMP) +.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1, invalidation_mode=None) Recursively descend the directory tree named by *dir*, compiling all :file:`.py` files along the way. Return a true value if all the files compiled successfully, @@ -185,10 +185,13 @@ Public functions .. versionchanged:: 3.7 The *invalidation_mode* parameter was added. + .. versionchanged:: 3.7.2 + The *invalidation_mode* parameter's default value is updated to None. + .. versionchanged:: 3.8 Setting *workers* to 0 now chooses the optimal number of cores. -.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, invalidation_mode=py_compile.PycInvalidationMode.TIMESTAMP) +.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, invalidation_mode=None) Compile the file with path *fullname*. Return a true value if the file compiled successfully, and a false value otherwise. @@ -232,7 +235,10 @@ Public functions .. versionchanged:: 3.7 The *invalidation_mode* parameter was added. -.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False, quiet=0, legacy=False, optimize=-1, invalidation_mode=py_compile.PycInvalidationMode.TIMESTAMP) + .. versionchanged:: 3.7.2 + The *invalidation_mode* parameter's default value is updated to None. + +.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False, quiet=0, legacy=False, optimize=-1, invalidation_mode=None) Byte-compile all the :file:`.py` files found along ``sys.path``. Return a true value if all the files compiled successfully, and a false value otherwise. @@ -255,6 +261,9 @@ Public functions .. versionchanged:: 3.7 The *invalidation_mode* parameter was added. + .. versionchanged:: 3.7.2 + The *invalidation_mode* parameter's default value is updated to None. + To force a recompile of all the :file:`.py` files in the :file:`Lib/` subdirectory and all its subdirectories:: diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index f2491dd24571be..41d47c7ef1530b 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -306,9 +306,10 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable. .. method:: cancel() - Attempt to cancel the call. If the call is currently being executed and - cannot be cancelled then the method will return ``False``, otherwise the - call will be cancelled and the method will return ``True``. + Attempt to cancel the call. If the call is currently being executed or + finished running and cannot be cancelled then the method will return + ``False``, otherwise the call will be cancelled and the method will + return ``True``. .. method:: cancelled() @@ -423,8 +424,9 @@ Module Functions Wait for the :class:`Future` instances (possibly created by different :class:`Executor` instances) given by *fs* to complete. Returns a named 2-tuple of sets. The first set, named ``done``, contains the futures that - completed (finished or were cancelled) before the wait completed. The second - set, named ``not_done``, contains uncompleted futures. + completed (finished or cancelled futures) before the wait completed. The + second set, named ``not_done``, contains the futures that did not complete + (pending or running futures). *timeout* can be used to control the maximum number of seconds to wait before returning. *timeout* can be an int or float. If *timeout* is not specified @@ -455,7 +457,7 @@ Module Functions Returns an iterator over the :class:`Future` instances (possibly created by different :class:`Executor` instances) given by *fs* that yields futures as - they complete (finished or were cancelled). Any futures given by *fs* that + 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__` diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index 04b52dc7b21531..739477f55fddda 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -313,6 +313,8 @@ from ``get()`` calls. my_dir: %(home_dir)s/lumberjack my_pictures: %(my_dir)s/Pictures + [Escape] + gain: 80%% # use a %% to escape the % sign (% is the only character that needs to be escaped) In the example above, :class:`ConfigParser` with *interpolation* set to ``BasicInterpolation()`` would resolve ``%(home_dir)s`` to the value of @@ -346,6 +348,9 @@ from ``get()`` calls. my_dir: ${home_dir}/lumberjack my_pictures: ${my_dir}/Pictures + [Escape] + cost: $$80 # use a $$ to escape the $ sign ($ is the only character that needs to be escaped) + Values from other sections can be fetched as well: .. code-block:: ini diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst index c7bd89f9637226..a8e8bfb1e832bb 100644 --- a/Doc/library/copy.rst +++ b/Doc/library/copy.rst @@ -31,6 +31,7 @@ Interface summary: Raised for module specific errors. +.. _shallow_vs_deep_copy: The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances): diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 97172c588ae97f..eb0bcf4ae2e368 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -576,7 +576,7 @@ Here is a simple example of a POINT structure, which contains two integers named >>> POINT(1, 2, 3) Traceback (most recent call last): File "", line 1, in - ValueError: too many initializers + TypeError: too many initializers >>> You can, however, build much more complicated structures. A structure can @@ -1175,16 +1175,21 @@ Keep in mind that retrieving sub-objects from Structure, Unions, and Arrays doesn't *copy* the sub-object, instead it retrieves a wrapper object accessing the root-object's underlying buffer. -Another example that may behave different from what one would expect is this:: +Another example that may behave differently from what one would expect is this:: >>> s = c_char_p() - >>> s.value = "abc def ghi" + >>> s.value = b"abc def ghi" >>> s.value - 'abc def ghi' + b'abc def ghi' >>> s.value is s.value False >>> +.. note:: + + Objects instantiated from :class:`c_char_p` can only have their value set to bytes + or integers. + Why is it printing ``False``? ctypes instances are objects containing a memory block plus some :term:`descriptor`\s accessing the contents of the memory. Storing a Python object in the memory block does not store the object itself, @@ -1509,13 +1514,13 @@ object is available: :c:type:`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 +.. audit-event:: ctypes.dlopen name ctypes.LibraryLoader Loading a library through any of these objects raises an :ref:`auditing event ` ``ctypes.dlopen`` with string argument ``name``, the name used to load the library. -.. audit-event:: ctypes.dlsym "library name" +.. audit-event:: ctypes.dlsym library,name ctypes.LibraryLoader Accessing a function on a loaded library raises an auditing event ``ctypes.dlsym`` with arguments ``library`` (the library object) and ``name`` @@ -2043,10 +2048,10 @@ Data types This method returns a ctypes type instance using the memory specified by *address* which must be an integer. - .. audit-event:: ctypes.cdata address + .. audit-event:: ctypes.cdata address ctypes._CData.from_address This method, and others that indirectly call this method, raises an - :func:`auditing event ` ``ctypes.cdata`` with argument + :ref:`auditing event ` ``ctypes.cdata`` with argument ``address``. .. method:: from_param(obj) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 7d1e7538a292b3..cbd68834b6cbee 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -1283,7 +1283,7 @@ The :mod:`curses` module defines the following data members: .. data:: ERR - Some curses routines that return an integer, such as :func:`getch`, return + Some curses routines that return an integer, such as :meth:`~window.getch`, return :const:`ERR` upon failure. diff --git a/Doc/library/datatypes.rst b/Doc/library/datatypes.rst index 48af0823aa4912..94010c0e391b0b 100644 --- a/Doc/library/datatypes.rst +++ b/Doc/library/datatypes.rst @@ -5,13 +5,14 @@ Data Types ********** The modules described in this chapter provide a variety of specialized data -types such as dates and times, fixed-type arrays, heap queues, synchronized -queues, and sets. +types such as dates and times, fixed-type arrays, heap queues, double-ended +queues, and enumerations. Python also provides some built-in data types, in particular, :class:`dict`, :class:`list`, :class:`set` and :class:`frozenset`, and :class:`tuple`. The :class:`str` class is used to hold -Unicode strings, and the :class:`bytes` class is used to hold binary data. +Unicode strings, and the :class:`bytes` and :class:`bytearray` classes are used +to hold binary data. The following modules are documented in this chapter: diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index fb41aeeb5bed03..b1e1b25691d8f1 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -14,40 +14,59 @@ .. XXX what order should the types be discussed in? -The :mod:`datetime` module supplies classes for manipulating dates and times in -both simple and complex ways. While date and time arithmetic is supported, the -focus of the implementation is on efficient attribute extraction for output -formatting and manipulation. For related functionality, see also the -:mod:`time` and :mod:`calendar` modules. - -There are two kinds of date and time objects: "naive" and "aware". - -An aware object has sufficient knowledge of applicable algorithmic and -political time adjustments, such as time zone and daylight saving time -information, to locate itself relative to other aware objects. An aware object -is used to represent a specific moment in time that is not open to -interpretation [#]_. - -A naive object does not contain enough information to unambiguously locate -itself relative to other date/time objects. Whether a naive object represents +The :mod:`datetime` module supplies classes for manipulating dates and times. + +While date and time arithmetic is supported, the focus of the implementation is +on efficient attribute extraction for output formatting and manipulation. + +.. seealso:: + + Module :mod:`calendar` + General calendar related functions. + + Module :mod:`time` + Time access and conversions. + + Package `dateutil `_ + Third-party library with expanded time zone and parsing support. + +.. _datetime-naive-aware: + +Aware and Naive Objects +----------------------- + +Date and time objects may be categorized as "aware" or "naive." + +With sufficient knowledge of applicable algorithmic and political time +adjustments, such as time zone and daylight saving time information, +an **aware** object can locate itself relative to other aware objects. +An aware object represents a specific moment in time that is not open to +interpretation. [#]_ + +A **naive** object does not contain enough information to unambiguously locate +itself relative to other date/time objects. Whether a naive object represents Coordinated Universal Time (UTC), local time, or time in some other timezone is purely up to the program, just like it is up to the program whether a -particular number represents metres, miles, or mass. Naive objects are easy to +particular number represents metres, miles, or mass. Naive objects are easy to understand and to work with, at the cost of ignoring some aspects of reality. For applications requiring aware objects, :class:`.datetime` and :class:`.time` objects have an optional time zone information attribute, :attr:`!tzinfo`, that can be set to an instance of a subclass of the abstract :class:`tzinfo` class. These :class:`tzinfo` objects capture information about the offset from UTC -time, the time zone name, and whether Daylight Saving Time is in effect. Note -that only one concrete :class:`tzinfo` class, the :class:`timezone` class, is -supplied by the :mod:`datetime` module. The :class:`timezone` class can -represent simple timezones with fixed offset from UTC, such as UTC itself or -North American EST and EDT timezones. Supporting timezones at deeper levels of -detail is up to the application. The rules for time adjustment across the +time, the time zone name, and whether daylight saving time is in effect. + +Only one concrete :class:`tzinfo` class, the :class:`timezone` class, is +supplied by the :mod:`datetime` module. The :class:`timezone` class can +represent simple timezones with fixed offsets from UTC, such as UTC itself or +North American EST and EDT timezones. Supporting timezones at deeper levels of +detail is up to the application. The rules for time adjustment across the world are more political than rational, change frequently, and there is no standard suitable for every application aside from UTC. +Constants +--------- + The :mod:`datetime` module exports the following constants: .. data:: MINYEAR @@ -61,16 +80,6 @@ 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``. - -.. seealso:: - - Module :mod:`calendar` - General calendar related functions. - - Module :mod:`time` - Time access and conversions. - - Available Types --------------- @@ -86,7 +95,7 @@ Available Types :noindex: An idealized time, independent of any particular day, assuming that every day - has exactly 24\*60\*60 seconds (there is no notion of "leap seconds" here). + has exactly 24\*60\*60 seconds. (There is no notion of "leap seconds" here.) Attributes: :attr:`hour`, :attr:`minute`, :attr:`second`, :attr:`microsecond`, and :attr:`.tzinfo`. @@ -109,7 +118,7 @@ Available Types .. class:: tzinfo :noindex: - An abstract base class for time zone information objects. These are used by the + An abstract base class for time zone information objects. These are used by the :class:`.datetime` and :class:`.time` classes to provide a customizable notion of time adjustment (for example, to account for time zone and/or daylight saving time). @@ -122,22 +131,8 @@ Available Types .. versionadded:: 3.2 - Objects of these types are immutable. -Objects of the :class:`date` type are always naive. - -An object of type :class:`.time` or :class:`.datetime` may be naive or aware. -A :class:`.datetime` object *d* is aware if ``d.tzinfo`` is not ``None`` and -``d.tzinfo.utcoffset(d)`` does not return ``None``. If ``d.tzinfo`` is -``None``, or if ``d.tzinfo`` is not ``None`` but ``d.tzinfo.utcoffset(d)`` -returns ``None``, *d* is naive. A :class:`.time` object *t* is aware -if ``t.tzinfo`` is not ``None`` and ``t.tzinfo.utcoffset(None)`` does not return -``None``. Otherwise, *t* is naive. - -The distinction between naive and aware doesn't apply to :class:`timedelta` -objects. - Subclass relationships:: object @@ -148,6 +143,40 @@ Subclass relationships:: date datetime +Common Properties +^^^^^^^^^^^^^^^^^ + +The :class:`date`, :class:`.datetime`, :class:`.time`, and :class:`timezone` types +share these common features: + +- Objects of these types are immutable. +- Objects of these types are hashable, meaning that they can be used as + dictionary keys. +- Objects of these types support efficient pickling via the :mod:`pickle` module. + +Determining if an Object is Aware or Naive +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Objects of the :class:`date` type are always naive. + +An object of type :class:`.time` or :class:`.datetime` may be aware or naive. + +A :class:`.datetime` object *d* is aware if both of the following hold: + +1. ``d.tzinfo`` is not ``None`` +2. ``d.tzinfo.utcoffset(d)`` does not return ``None`` + +Otherwise, *d* is naive. + +A :class:`.time` object *t* is aware if both of the following hold: + +1. ``t.tzinfo`` is not ``None`` +2. ``t.tzinfo.utcoffset(None)`` does not return ``None``. + +Otherwise, *t* is naive. + +The distinction between aware and naive doesn't apply to :class:`timedelta` +objects. .. _datetime-timedelta: @@ -159,11 +188,11 @@ dates or times. .. class:: timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0) - All arguments are optional and default to ``0``. Arguments may be integers + All arguments are optional and default to ``0``. Arguments may be integers or floats, and may be positive or negative. - Only *days*, *seconds* and *microseconds* are stored internally. Arguments are - converted to those units: + Only *days*, *seconds* and *microseconds* are stored internally. + Arguments are converted to those units: * A millisecond is converted to 1000 microseconds. * A minute is converted to 60 seconds. @@ -177,10 +206,28 @@ dates or times. * ``0 <= seconds < 3600*24`` (the number of seconds in one day) * ``-999999999 <= days <= 999999999`` + The following example illustrates how any arguments besides + *days*, *seconds* and *microseconds* are "merged" and normalized into those + three resulting attributes:: + + >>> from datetime import timedelta + >>> delta = timedelta( + ... days=50, + ... seconds=27, + ... microseconds=10, + ... milliseconds=29000, + ... minutes=5, + ... hours=8, + ... weeks=2 + ... ) + >>> # Only days, seconds, and microseconds remain + >>> delta + datetime.timedelta(days=64, seconds=29156, microseconds=10) + If any argument is a float and there are fractional microseconds, the fractional microseconds left over from all arguments are combined and their sum is rounded to the nearest microsecond using - round-half-to-even tiebreaker. If no argument is a float, the + round-half-to-even tiebreaker. If no argument is a float, the conversion and normalization processes are exact (no information is lost). @@ -188,7 +235,7 @@ dates or times. :exc:`OverflowError` is raised. Note that normalization of negative values may be surprising at first. For - example, + example:: >>> from datetime import timedelta >>> d = timedelta(microseconds=-1) @@ -196,7 +243,7 @@ dates or times. (-1, 86399, 999999) -Class attributes are: +Class attributes: .. attribute:: timedelta.min @@ -263,7 +310,7 @@ Supported operations: | | timedelta.resolution using round-half-to-even.| +--------------------------------+-----------------------------------------------+ | ``t1 = t2 // i`` or | The floor is computed and the remainder (if | -| ``t1 = t2 // t3`` | any) is thrown away. In the second case, an | +| ``t1 = t2 // t3`` | any) is thrown away. In the second case, an | | | integer is returned. (3) | +--------------------------------+-----------------------------------------------+ | ``t1 = t2 % t3`` | The remainder is computed as a | @@ -282,8 +329,8 @@ Supported operations: | | -*t1.seconds*, -*t1.microseconds*), | | | and to *t1*\* -1. (1)(4) | +--------------------------------+-----------------------------------------------+ -| ``abs(t)`` | equivalent to +\ *t* when ``t.days >= 0``, and| -| | to -*t* when ``t.days < 0``. (2) | +| ``abs(t)`` | equivalent to +\ *t* when ``t.days >= 0``, | +| | and to -*t* when ``t.days < 0``. (2) | +--------------------------------+-----------------------------------------------+ | ``str(t)`` | Returns a string in the form | | | ``[D day[s], ][H]H:MM:SS[.UUUUUU]``, where D | @@ -298,10 +345,10 @@ Supported operations: Notes: (1) - This is exact, but may overflow. + This is exact but may overflow. (2) - This is exact, and cannot overflow. + This is exact and cannot overflow. (3) Division by 0 raises :exc:`ZeroDivisionError`. @@ -310,41 +357,56 @@ Notes: -*timedelta.max* is not representable as a :class:`timedelta` object. (5) - String representations of :class:`timedelta` objects are normalized - similarly to their internal representation. This leads to somewhat - unusual results for negative timedeltas. For example: + String representations of :class:`timedelta` objects are normalized + similarly to their internal representation. This leads to somewhat + unusual results for negative timedeltas. For example:: - >>> timedelta(hours=-5) - datetime.timedelta(days=-1, seconds=68400) - >>> print(_) - -1 day, 19:00:00 + >>> timedelta(hours=-5) + datetime.timedelta(days=-1, seconds=68400) + >>> print(_) + -1 day, 19:00:00 (6) The expression ``t2 - t3`` will always be equal to the expression ``t2 + (-t3)`` except when t3 is equal to ``timedelta.max``; in that case the former will produce a result while the latter will overflow. -In addition to the operations listed above :class:`timedelta` objects support +In addition to the operations listed above, :class:`timedelta` objects support certain additions and subtractions with :class:`date` and :class:`.datetime` objects (see below). .. versionchanged:: 3.2 Floor division and true division of a :class:`timedelta` object by another :class:`timedelta` object are now supported, as are remainder operations and - the :func:`divmod` function. True division and multiplication of a + the :func:`divmod` function. True division and multiplication of a :class:`timedelta` object by a :class:`float` object are now supported. -Comparisons of :class:`timedelta` objects are supported with the -:class:`timedelta` object representing the smaller duration considered to be the -smaller timedelta. In order to stop mixed-type comparisons from falling back to -the default comparison by object address, when a :class:`timedelta` object is -compared to an object of a different type, :exc:`TypeError` is raised unless the -comparison is ``==`` or ``!=``. The latter cases return :const:`False` or -:const:`True`, respectively. +Comparisons of :class:`timedelta` objects are supported, with some caveats. + +The comparisons ``==`` or ``!=`` *always* return a :class:`bool`, no matter +the type of the compared object:: + + >>> from datetime import timedelta + >>> delta1 = timedelta(seconds=57) + >>> delta2 = timedelta(hours=25, seconds=2) + >>> delta2 != delta1 + True + >>> delta2 == 5 + False + +For all other comparisons (such as ``<`` and ``>``), when a :class:`timedelta` +object is compared to an object of a different type, :exc:`TypeError` +is raised:: + + >>> delta2 > delta1 + True + >>> delta2 > 5 + Traceback (most recent call last): + File "", line 1, in + TypeError: '>' not supported between instances of 'datetime.timedelta' and 'int' -:class:`timedelta` objects are :term:`hashable` (usable as dictionary keys), support -efficient pickling, and in Boolean contexts, a :class:`timedelta` object is +In Boolean contexts, a :class:`timedelta` object is considered to be true if and only if it isn't equal to ``timedelta(0)``. Instance methods: @@ -360,29 +422,36 @@ Instance methods: .. versionadded:: 3.2 +Examples of usage: :class:`timedelta` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Example usage: +An additional example of normalization:: + >>> # Components of another_year add up to exactly 365 days >>> from datetime import timedelta >>> year = timedelta(days=365) >>> another_year = timedelta(weeks=40, days=84, hours=23, - ... minutes=50, seconds=600) # adds up to 365 days - >>> year.total_seconds() - 31536000.0 + ... minutes=50, seconds=600) >>> year == another_year True + >>> year.total_seconds() + 31536000.0 + +Examples of :class:`timedelta` arithmetic:: + + >>> from datetime import timedelta + >>> year = timedelta(days=365) >>> ten_years = 10 * year - >>> ten_years, ten_years.days // 365 - (datetime.timedelta(days=3650), 10) + >>> ten_years + datetime.timedelta(days=3650) + >>> ten_years.days // 365 + 10 >>> nine_years = ten_years - year - >>> nine_years, nine_years.days // 365 - (datetime.timedelta(days=3285), 9) + >>> nine_years + datetime.timedelta(days=3285) >>> three_years = nine_years // 3 >>> three_years, three_years.days // 365 (datetime.timedelta(days=1095), 3) - >>> abs(three_years - ten_years) == 2 * three_years + year - True - .. _datetime-date: @@ -391,17 +460,14 @@ Example usage: A :class:`date` object represents a date (year, month and day) in an idealized calendar, the current Gregorian calendar indefinitely extended in both -directions. January 1 of year 1 is called day number 1, January 2 of year 1 is -called day number 2, and so on. This matches the definition of the "proleptic -Gregorian" calendar in Dershowitz and Reingold's book Calendrical Calculations, -where it's the base calendar for all computations. See the book for algorithms -for converting between proleptic Gregorian ordinals and many other calendar -systems. +directions. +January 1 of year 1 is called day number 1, January 2 of year 1 is +called day number 2, and so on. [#]_ .. class:: date(year, month, day) - All arguments are required. Arguments may be integers, in the following + All arguments are required. Arguments must be integers, in the following ranges: * ``MINYEAR <= year <= MAXYEAR`` @@ -415,17 +481,19 @@ Other constructors, all class methods: .. classmethod:: date.today() - Return the current local date. This is equivalent to - ``date.fromtimestamp(time.time())``. + Return the current local date. + This is equivalent to ``date.fromtimestamp(time.time())``. .. classmethod:: date.fromtimestamp(timestamp) - Return the local date corresponding to the POSIX timestamp, such as is returned - by :func:`time.time`. This may raise :exc:`OverflowError`, if the timestamp is out - of the range of values supported by the platform C :c:func:`localtime` function, - and :exc:`OSError` on :c:func:`localtime` failure. - It's common for this to be restricted to years from 1970 through 2038. Note + Return the local date corresponding to the POSIX timestamp, such as is + returned by :func:`time.time`. + + This may raise :exc:`OverflowError`, if the timestamp is out + of the range of values supported by the platform C :c:func:`localtime` + function, and :exc:`OSError` on :c:func:`localtime` failure. + It's common for this to be restricted to years from 1970 through 2038. Note that on non-POSIX systems that include leap seconds in their notion of a timestamp, leap seconds are ignored by :meth:`fromtimestamp`. @@ -438,24 +506,27 @@ Other constructors, all class methods: .. classmethod:: date.fromordinal(ordinal) - Return the date corresponding to the proleptic Gregorian ordinal, where January - 1 of year 1 has ordinal 1. :exc:`ValueError` is raised unless ``1 <= ordinal <= - date.max.toordinal()``. For any date *d*, ``date.fromordinal(d.toordinal()) == - d``. + Return the date corresponding to the proleptic Gregorian ordinal, where + January 1 of year 1 has ordinal 1. + + :exc:`ValueError` is raised unless ``1 <= ordinal <= + date.max.toordinal()``. For any date *d*, + ``date.fromordinal(d.toordinal()) == d``. .. classmethod:: date.fromisoformat(date_string) - Return a :class:`date` corresponding to a *date_string* in the format emitted - by :meth:`date.isoformat`. Specifically, this function supports strings in - the format(s) ``YYYY-MM-DD``. + Return a :class:`date` corresponding to a *date_string* given in the format + ``YYYY-MM-DD``:: - .. caution:: + >>> from datetime import date + >>> date.fromisoformat('2019-12-04') + datetime.date(2019, 12, 4) - This does not support parsing arbitrary ISO 8601 strings - it is only intended - as the inverse operation of :meth:`date.isoformat`. + This is the inverse of :meth:`date.isoformat`. It only supports the format + ``YYYY-MM-DD``. - .. versionadded:: 3.7 + .. versionadded:: 3.7 .. classmethod:: date.fromisocalendar(year, week, day) @@ -507,7 +578,7 @@ Supported operations: | Operation | Result | +===============================+==============================================+ | ``date2 = date1 + timedelta`` | *date2* is ``timedelta.days`` days removed | -| | from *date1*. (1) | +| | from *date1*. (1) | +-------------------------------+----------------------------------------------+ | ``date2 = date1 - timedelta`` | Computes *date2* such that ``date2 + | | | timedelta == date1``. (2) | @@ -522,7 +593,7 @@ Notes: (1) *date2* is moved forward in time if ``timedelta.days > 0``, or backward if - ``timedelta.days < 0``. Afterward ``date2 - date1 == timedelta.days``. + ``timedelta.days < 0``. Afterward ``date2 - date1 == timedelta.days``. ``timedelta.seconds`` and ``timedelta.microseconds`` are ignored. :exc:`OverflowError` is raised if ``date2.year`` would be smaller than :const:`MINYEAR` or larger than :const:`MAXYEAR`. @@ -531,7 +602,7 @@ Notes: ``timedelta.seconds`` and ``timedelta.microseconds`` are ignored. (3) - This is exact, and cannot overflow. timedelta.seconds and + This is exact, and cannot overflow. timedelta.seconds and timedelta.microseconds are 0, and date2 + timedelta == date1 after. (4) @@ -539,38 +610,47 @@ Notes: date2.toordinal()``. Date comparison raises :exc:`TypeError` if the other comparand isn't also a :class:`date` object. However, ``NotImplemented`` is returned instead if the other comparand has a - :meth:`timetuple` attribute. This hook gives other kinds of date objects a + :meth:`timetuple` attribute. This hook gives other kinds of date objects a chance at implementing mixed-type comparison. If not, when a :class:`date` object is compared to an object of a different type, :exc:`TypeError` is raised - unless the comparison is ``==`` or ``!=``. The latter cases return + unless the comparison is ``==`` or ``!=``. The latter cases return :const:`False` or :const:`True`, respectively. -Dates can be used as dictionary keys. In Boolean contexts, all :class:`date` -objects are considered to be true. +In Boolean contexts, all :class:`date` objects are considered to be true. Instance methods: .. method:: date.replace(year=self.year, month=self.month, day=self.day) Return a date with the same value, except for those parameters given new - values by whichever keyword arguments are specified. For example, if ``d == - date(2002, 12, 31)``, then ``d.replace(day=26) == date(2002, 12, 26)``. + values by whichever keyword arguments are specified. + + Example:: + + >>> from datetime import date + >>> d = date(2002, 12, 31) + >>> d.replace(day=26) + datetime.date(2002, 12, 26) .. method:: date.timetuple() Return a :class:`time.struct_time` such as returned by :func:`time.localtime`. - The hours, minutes and seconds are 0, and the DST flag is -1. ``d.timetuple()`` - is equivalent to ``time.struct_time((d.year, d.month, d.day, 0, 0, 0, - d.weekday(), yday, -1))``, where ``yday = d.toordinal() - date(d.year, 1, - 1).toordinal() + 1`` is the day number within the current year starting with - ``1`` for January 1st. + + The hours, minutes and seconds are 0, and the DST flag is -1. + + ``d.timetuple()`` is equivalent to:: + + time.struct_time((d.year, d.month, d.day, 0, 0, 0, d.weekday(), yday, -1)) + + where ``yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1`` + is the day number within the current year starting with ``1`` for January 1st. .. method:: date.toordinal() Return the proleptic Gregorian ordinal of the date, where January 1 of year 1 - has ordinal 1. For any :class:`date` object *d*, + has ordinal 1. For any :class:`date` object *d*, ``date.fromordinal(d.toordinal()) == d``. @@ -592,26 +672,31 @@ Instance methods: Return a 3-tuple, (ISO year, ISO week number, ISO weekday). - The ISO calendar is a widely used variant of the Gregorian calendar. See - https://www.staff.science.uu.nl/~gent0113/calendar/isocalendar.htm for a good - explanation. + The ISO calendar is a widely used variant of the Gregorian calendar. [#]_ The ISO year consists of 52 or 53 full weeks, and where a week starts on a - Monday and ends on a Sunday. The first week of an ISO year is the first + Monday and ends on a Sunday. The first week of an ISO year is the first (Gregorian) calendar week of a year containing a Thursday. This is called week number 1, and the ISO year of that Thursday is the same as its Gregorian year. For example, 2004 begins on a Thursday, so the first week of ISO year 2004 - begins on Monday, 29 Dec 2003 and ends on Sunday, 4 Jan 2004, so that - ``date(2003, 12, 29).isocalendar() == (2004, 1, 1)`` and ``date(2004, 1, - 4).isocalendar() == (2004, 1, 7)``. + begins on Monday, 29 Dec 2003 and ends on Sunday, 4 Jan 2004:: + >>> from datetime import date + >>> date(2003, 12, 29).isocalendar() + (2004, 1, 1) + >>> date(2004, 1, 4).isocalendar() + (2004, 1, 7) .. method:: date.isoformat() - Return a string representing the date in ISO 8601 format, 'YYYY-MM-DD'. For - example, ``date(2002, 12, 4).isoformat() == '2002-12-04'``. + Return a string representing the date in ISO 8601 format, ``YYYY-MM-DD``:: + + >>> from datetime import date + >>> date(2002, 12, 4).isoformat() + '2002-12-04' + This is the inverse of :meth:`date.fromisoformat`. .. method:: date.__str__() @@ -620,9 +705,17 @@ Instance methods: .. method:: date.ctime() - Return a string representing the date, for example ``date(2002, 12, - 4).ctime() == 'Wed Dec 4 00:00:00 2002'``. ``d.ctime()`` is equivalent to - ``time.ctime(time.mktime(d.timetuple()))`` on platforms where the native C + Return a string representing the date:: + + >>> from datetime import date + >>> date(2002, 12, 4).ctime() + 'Wed Dec 4 00:00:00 2002' + + ``d.ctime()`` is equivalent to:: + + time.ctime(time.mktime(d.timetuple())) + + on platforms where the native C :c:func:`ctime` function (which :func:`time.ctime` invokes, but which :meth:`date.ctime` does not invoke) conforms to the C standard. @@ -643,6 +736,8 @@ Instance methods: complete list of formatting directives, see :ref:`strftime-strptime-behavior`. +Examples of Usage: :class:`date` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Example of counting days to an event:: @@ -662,7 +757,7 @@ Example of counting days to an event:: >>> time_to_birthday.days 202 -Example of working with :class:`date`: +More examples of working with :class:`date`: .. doctest:: @@ -670,6 +765,20 @@ Example of working with :class:`date`: >>> d = date.fromordinal(730920) # 730920th day after 1. 1. 0001 >>> d datetime.date(2002, 3, 11) + + >>> # Methods related to formatting string output + >>> d.isoformat() + '2002-03-11' + >>> d.strftime("%d/%m/%y") + '11/03/02' + >>> d.strftime("%A %d. %B %Y") + 'Monday 11. March 2002' + >>> d.ctime() + 'Mon Mar 11 00:00:00 2002' + >>> 'The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day", "month") + 'The day is 11, the month is March.' + + >>> # Methods for to extracting 'components' under different calendars >>> t = d.timetuple() >>> for i in t: # doctest: +SKIP ... print(i) @@ -688,14 +797,10 @@ Example of working with :class:`date`: 2002 # ISO year 11 # ISO week number 1 # ISO day number ( 1 = Monday ) - >>> d.isoformat() - '2002-03-11' - >>> d.strftime("%d/%m/%y") - '11/03/02' - >>> d.strftime("%A %d. %B %Y") - 'Monday 11. March 2002' - >>> 'The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day", "month") - 'The day is 11, the month is March.' + + >>> # A date object is immutable; all operations produce a new object + >>> d.replace(year=2005) + datetime.date(2005, 3, 11) .. _datetime-datetime: @@ -704,17 +809,18 @@ Example of working with :class:`date`: -------------------------- A :class:`.datetime` object is a single object containing all the information -from a :class:`date` object and a :class:`.time` object. Like a :class:`date` -object, :class:`.datetime` assumes the current Gregorian calendar extended in -both directions; like a time object, :class:`.datetime` assumes there are exactly -3600\*24 seconds in every day. +from a :class:`date` object and a :class:`.time` object. + +Like a :class:`date` object, :class:`.datetime` assumes the current Gregorian +calendar extended in both directions; like a :class:`.time` object, +:class:`.datetime` assumes there are exactly 3600\*24 seconds in every day. Constructor: .. class:: datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0) - The year, month and day arguments are required. *tzinfo* may be ``None``, or an - instance of a :class:`tzinfo` subclass. The remaining arguments may be integers, + The *year*, *month* and *day* arguments are required. *tzinfo* may be ``None``, or an + instance of a :class:`tzinfo` subclass. The remaining arguments must be integers in the following ranges: * ``MINYEAR <= year <= MAXYEAR``, @@ -735,31 +841,48 @@ Other constructors, all class methods: .. classmethod:: datetime.today() - Return the current local datetime, with :attr:`.tzinfo` ``None``. This is - equivalent to ``datetime.fromtimestamp(time.time())``. See also :meth:`now`, - :meth:`fromtimestamp`. + Return the current local datetime, with :attr:`.tzinfo` ``None``. + + Equivalent to:: + + datetime.fromtimestamp(time.time()) + See also :meth:`now`, :meth:`fromtimestamp`. + + This method is functionally equivalent to :meth:`now`, but without a + ``tz`` parameter. .. classmethod:: datetime.now(tz=None) - Return the current local date and time. If optional argument *tz* is ``None`` + Return the current local date and time. + + If optional argument *tz* is ``None`` or not specified, this is like :meth:`today`, but, if possible, supplies more precision than can be gotten from going through a :func:`time.time` timestamp (for example, this may be possible on platforms supplying the C :c:func:`gettimeofday` function). - If *tz* is not ``None``, it must be an instance of a :class:`tzinfo` subclass, and the - current date and time are converted to *tz*’s time zone. In this case the - result is equivalent to ``tz.fromutc(datetime.utcnow().replace(tzinfo=tz))``. - See also :meth:`today`, :meth:`utcnow`. + If *tz* is not ``None``, it must be an instance of a :class:`tzinfo` subclass, + and the current date and time are converted to *tz*’s time zone. + + This function is preferred over :meth:`today` and :meth:`utcnow`. .. classmethod:: datetime.utcnow() - Return the current UTC date and time, with :attr:`.tzinfo` ``None``. This is like - :meth:`now`, but returns the current UTC date and time, as a naive - :class:`.datetime` object. An aware current UTC datetime can be obtained by - calling ``datetime.now(timezone.utc)``. See also :meth:`now`. + Return the current UTC date and time, with :attr:`.tzinfo` ``None``. + + This is like :meth:`now`, but returns the current UTC date and time, as a naive + :class:`.datetime` object. An aware current UTC datetime can be obtained by + calling ``datetime.now(timezone.utc)``. See also :meth:`now`. + + .. warning:: + + 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 such, the recommended way to create an object representing the + current time in UTC by calling ``datetime.now(timezone.utc)``. + .. classmethod:: datetime.fromtimestamp(timestamp, tz=None) @@ -769,9 +892,7 @@ Other constructors, all class methods: the returned :class:`.datetime` object is naive. If *tz* is not ``None``, it must be an instance of a :class:`tzinfo` subclass, and the - timestamp is converted to *tz*’s time zone. In this case the result is - equivalent to - ``tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz))``. + timestamp is converted to *tz*’s time zone. :meth:`fromtimestamp` may raise :exc:`OverflowError`, if the timestamp is out of the range of values supported by the platform C :c:func:`localtime` or @@ -781,7 +902,8 @@ Other constructors, all class methods: 1970 through 2038. Note that on non-POSIX systems that include leap seconds in their notion of a timestamp, leap seconds are ignored by :meth:`fromtimestamp`, and then it's possible to have two timestamps differing by a second that yield - identical :class:`.datetime` objects. See also :meth:`utcfromtimestamp`. + identical :class:`.datetime` objects. This method is preferred over + :meth:`utcfromtimestamp`. .. versionchanged:: 3.3 Raise :exc:`OverflowError` instead of :exc:`ValueError` if the timestamp @@ -796,7 +918,9 @@ Other constructors, all class methods: .. classmethod:: datetime.utcfromtimestamp(timestamp) Return the UTC :class:`.datetime` corresponding to the POSIX timestamp, with - :attr:`.tzinfo` ``None``. This may raise :exc:`OverflowError`, if the timestamp is + :attr:`.tzinfo` ``None``. (The resulting object is naive.) + + This may raise :exc:`OverflowError`, if the timestamp is out of the range of values supported by the platform C :c:func:`gmtime` function, and :exc:`OSError` on :c:func:`gmtime` failure. It's common for this to be restricted to years in 1970 through 2038. @@ -813,6 +937,14 @@ Other constructors, all class methods: except the latter formula always supports the full years range: between :const:`MINYEAR` and :const:`MAXYEAR` inclusive. + .. warning:: + + 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 such, the recommended way to create an object representing a + specific timestamp in UTC by calling + ``datetime.fromtimestamp(timestamp, tz=timezone.utc)``. + .. versionchanged:: 3.3 Raise :exc:`OverflowError` instead of :exc:`ValueError` if the timestamp is out of the range of values supported by the platform C @@ -824,7 +956,7 @@ Other constructors, all class methods: Return the :class:`.datetime` corresponding to the proleptic Gregorian ordinal, where January 1 of year 1 has ordinal 1. :exc:`ValueError` is raised unless ``1 - <= ordinal <= datetime.max.toordinal()``. The hour, minute, second and + <= ordinal <= datetime.max.toordinal()``. The hour, minute, second and microsecond of the result are all 0, and :attr:`.tzinfo` is ``None``. @@ -832,13 +964,13 @@ Other constructors, all class methods: Return a new :class:`.datetime` object whose date components are equal to the given :class:`date` object's, and whose time components - are equal to the given :class:`.time` object's. If the *tzinfo* + 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. For any :class:`.datetime` object *d*, - ``d == datetime.combine(d.date(), d.time(), d.tzinfo)``. If date is a + ``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. @@ -848,23 +980,46 @@ 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`. - Specifically, this function supports strings in the format(s) - ``YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]``, - where ``*`` can match any single character. + Return a :class:`.datetime` corresponding to a *date_string* in one of the + formats emitted by :meth:`date.isoformat` and :meth:`datetime.isoformat`. + + Specifically, this function supports strings in the format: + + .. code-block:: none + + YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]] - .. caution:: + where ``*`` can match any single character. - This does not support parsing arbitrary ISO 8601 strings - it is only intended - as the inverse operation of :meth:`datetime.isoformat`. + .. caution:: - .. versionadded:: 3.7 + 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 `__. + This does not support parsing arbitrary ISO 8601 strings - it is only intended + as the inverse operation of :meth:`datetime.isoformat`. + Examples:: + + >>> from datetime import datetime + >>> datetime.fromisoformat('2011-11-04') + 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-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') + datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc) + >>> datetime.fromisoformat('2011-11-04T00:05:23+04:00') # doctest: +NORMALIZE_WHITESPACE + datetime.datetime(2011, 11, 4, 0, 5, 23, + tzinfo=datetime.timezone(datetime.timedelta(seconds=14400))) + + .. versionadded:: 3.7 .. classmethod:: datetime.fromisocalendar(year, week, day) - Return a :class:`datetime` corresponding to the ISO calendar date specified + Return a :class:`.datetime` corresponding to the ISO calendar date specified by year, week and day. The non-date components of the datetime are populated with their normal default values. This is the inverse of the function :meth:`datetime.isocalendar`. @@ -874,8 +1029,13 @@ Other constructors, all class methods: .. classmethod:: datetime.strptime(date_string, format) Return a :class:`.datetime` corresponding to *date_string*, parsed according to - *format*. This is equivalent to ``datetime(*(time.strptime(date_string, - format)[0:6]))``. :exc:`ValueError` is raised if the date_string and format + *format*. + + This is equivalent to:: + + datetime(*(time.strptime(date_string, format)[0:6])) + + :exc:`ValueError` is raised if the date_string and format can't be parsed by :func:`time.strptime` or if it returns a value which isn't a time tuple. For a complete list of formatting directives, see :ref:`strftime-strptime-behavior`. @@ -947,7 +1107,7 @@ Instance attributes (read-only): .. attribute:: datetime.fold - In ``[0, 1]``. Used to disambiguate wall times during a repeated interval. (A + In ``[0, 1]``. Used to disambiguate wall times during a repeated interval. (A repeated interval occurs when clocks are rolled back at the end of daylight saving time or when the UTC offset for the current zone is decreased for political reasons.) The value 0 (1) represents the earlier (later) of the two moments with the same wall @@ -972,7 +1132,7 @@ Supported operations: (1) datetime2 is a duration of timedelta removed from datetime1, moving forward in - time if ``timedelta.days`` > 0, or backward if ``timedelta.days`` < 0. The + time if ``timedelta.days`` > 0, or backward if ``timedelta.days`` < 0. The result has the same :attr:`~.datetime.tzinfo` attribute as the input datetime, and datetime2 - datetime1 == timedelta after. :exc:`OverflowError` is raised if datetime2.year would be smaller than :const:`MINYEAR` or larger than @@ -986,16 +1146,16 @@ Supported operations: (3) Subtraction of a :class:`.datetime` from a :class:`.datetime` is defined only if - both operands are naive, or if both are aware. If one is aware and the other is + both operands are naive, or if both are aware. If one is aware and the other is naive, :exc:`TypeError` is raised. If both are naive, or both are aware and have the same :attr:`~.datetime.tzinfo` attribute, the :attr:`~.datetime.tzinfo` attributes are ignored, and the result is a :class:`timedelta` - object *t* such that ``datetime2 + t == datetime1``. No time zone adjustments + object *t* such that ``datetime2 + t == datetime1``. No time zone adjustments are done in this case. If both are aware and have different :attr:`~.datetime.tzinfo` attributes, ``a-b`` acts - as if *a* and *b* were first converted to naive UTC datetimes first. The + as if *a* and *b* were first converted to naive UTC datetimes first. The result is ``(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset())`` except that the implementation never overflows. @@ -1004,34 +1164,31 @@ Supported operations: *datetime2* in time. If one comparand is naive and the other is aware, :exc:`TypeError` - is raised if an order comparison is attempted. For equality + is raised if an order comparison is attempted. For equality comparisons, naive instances are never equal to aware instances. If both comparands are aware, and have the same :attr:`~.datetime.tzinfo` attribute, the common :attr:`~.datetime.tzinfo` attribute is ignored and the base datetimes are - compared. If both comparands are aware and have different :attr:`~.datetime.tzinfo` + compared. If both comparands are aware and have different :attr:`~.datetime.tzinfo` attributes, the comparands are first adjusted by subtracting their UTC offsets (obtained from ``self.utcoffset()``). .. versionchanged:: 3.3 - Equality comparisons between naive and aware :class:`.datetime` + Equality comparisons between aware and naive :class:`.datetime` instances don't raise :exc:`TypeError`. .. note:: In order to stop comparison from falling back to the default scheme of comparing object addresses, datetime comparison normally raises :exc:`TypeError` if the - other comparand isn't also a :class:`.datetime` object. However, + other comparand isn't also a :class:`.datetime` object. However, ``NotImplemented`` is returned instead if the other comparand has a - :meth:`timetuple` attribute. This hook gives other kinds of date objects a - chance at implementing mixed-type comparison. If not, when a :class:`.datetime` + :meth:`timetuple` attribute. This hook gives other kinds of date objects a + chance at implementing mixed-type comparison. If not, when a :class:`.datetime` object is compared to an object of a different type, :exc:`TypeError` is raised - unless the comparison is ``==`` or ``!=``. The latter cases return + unless the comparison is ``==`` or ``!=``. The latter cases return :const:`False` or :const:`True`, respectively. -:class:`.datetime` objects can be used as dictionary keys. In Boolean contexts, -all :class:`.datetime` objects are considered to be true. - Instance methods: .. method:: datetime.date() @@ -1042,7 +1199,7 @@ Instance methods: .. method:: datetime.time() Return :class:`.time` object with same hour, minute, second, microsecond and fold. - :attr:`.tzinfo` is ``None``. See also method :meth:`timetz`. + :attr:`.tzinfo` is ``None``. See also method :meth:`timetz`. .. versionchanged:: 3.6 The fold value is copied to the returned :class:`.time` object. @@ -1051,7 +1208,7 @@ Instance methods: .. method:: datetime.timetz() Return :class:`.time` object with same hour, minute, second, microsecond, fold, and - tzinfo attributes. See also method :meth:`time`. + tzinfo attributes. See also method :meth:`time`. .. versionchanged:: 3.6 The fold value is copied to the returned :class:`.time` object. @@ -1062,7 +1219,7 @@ Instance methods: tzinfo=self.tzinfo, * fold=0) Return a datetime with the same attributes, except for those attributes given - new values by whichever keyword arguments are specified. Note that + new values by whichever keyword arguments are specified. Note that ``tzinfo=None`` can be specified to create a naive datetime from an aware datetime with no conversion of date and time data. @@ -1077,11 +1234,11 @@ Instance methods: *self*, but in *tz*'s local time. If provided, *tz* must be an instance of a :class:`tzinfo` subclass, and its - :meth:`utcoffset` and :meth:`dst` methods must not return ``None``. If *self* + :meth:`utcoffset` and :meth:`dst` methods must not return ``None``. If *self* is naive, it is presumed to represent time in the system timezone. If called without arguments (or with ``tz=None``) the system local - timezone is assumed for the target timezone. The ``.tzinfo`` attribute of the converted + timezone is assumed for the target timezone. The ``.tzinfo`` attribute of the converted datetime instance will be set to an instance of :class:`timezone` with the zone name and offset obtained from the OS. @@ -1092,7 +1249,7 @@ Instance methods: the same date and time data as ``dt - dt.utcoffset()``. If you merely want to attach a time zone object *tz* to a datetime *dt* without - adjustment of date and time data, use ``dt.replace(tzinfo=tz)``. If you + adjustment of date and time data, use ``dt.replace(tzinfo=tz)``. If you merely want to remove the time zone object from an aware datetime *dt* without conversion of date and time data, use ``dt.replace(tzinfo=None)``. @@ -1146,44 +1303,58 @@ Instance methods: .. method:: datetime.timetuple() Return a :class:`time.struct_time` such as returned by :func:`time.localtime`. - ``d.timetuple()`` is equivalent to ``time.struct_time((d.year, d.month, d.day, - d.hour, d.minute, d.second, d.weekday(), yday, dst))``, where ``yday = - d.toordinal() - date(d.year, 1, 1).toordinal() + 1`` is the day number within - the current year starting with ``1`` for January 1st. The :attr:`tm_isdst` flag - of the result is set according to the :meth:`dst` method: :attr:`.tzinfo` is - ``None`` or :meth:`dst` returns ``None``, :attr:`tm_isdst` is set to ``-1``; - else if :meth:`dst` returns a non-zero value, :attr:`tm_isdst` is set to ``1``; - else :attr:`tm_isdst` is set to ``0``. + + ``d.timetuple()`` is equivalent to:: + + time.struct_time((d.year, d.month, d.day, + d.hour, d.minute, d.second, + d.weekday(), yday, dst)) + + where ``yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1`` + is the day number within the current year starting with ``1`` for January + 1st. The :attr:`tm_isdst` flag of the result is set according to the + :meth:`dst` method: :attr:`.tzinfo` is ``None`` or :meth:`dst` returns + ``None``, :attr:`tm_isdst` is set to ``-1``; else if :meth:`dst` returns a + non-zero value, :attr:`tm_isdst` is set to ``1``; else :attr:`tm_isdst` is + set to ``0``. .. method:: datetime.utctimetuple() If :class:`.datetime` instance *d* is naive, this is the same as ``d.timetuple()`` except that :attr:`tm_isdst` is forced to 0 regardless of what - ``d.dst()`` returns. DST is never in effect for a UTC time. + ``d.dst()`` returns. DST is never in effect for a UTC time. If *d* is aware, *d* is normalized to UTC time, by subtracting ``d.utcoffset()``, and a :class:`time.struct_time` for the - normalized time is returned. :attr:`tm_isdst` is forced to 0. Note + normalized time is returned. :attr:`tm_isdst` is forced to 0. Note that an :exc:`OverflowError` may be raised if *d*.year was ``MINYEAR`` or ``MAXYEAR`` and UTC adjustment spills over a year boundary. + .. warning:: + + 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 + 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`. .. method:: datetime.toordinal() - Return the proleptic Gregorian ordinal of the date. The same as + Return the proleptic Gregorian ordinal of the date. The same as ``self.date().toordinal()``. .. method:: datetime.timestamp() Return POSIX timestamp corresponding to the :class:`.datetime` - instance. The return value is a :class:`float` similar to that + instance. The return value is a :class:`float` similar to that returned by :func:`time.time`. Naive :class:`.datetime` instances are assumed to represent local time and this method relies on the platform C :c:func:`mktime` - function to perform the conversion. Since :class:`.datetime` + 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. @@ -1202,7 +1373,7 @@ Instance methods: .. note:: There is no method to obtain the POSIX timestamp directly from a - naive :class:`.datetime` instance representing UTC time. If your + naive :class:`.datetime` instance representing UTC time. If your application uses this convention and your system timezone is not set to UTC, you can obtain the POSIX timestamp by supplying ``tzinfo=timezone.utc``:: @@ -1228,30 +1399,45 @@ Instance methods: .. method:: datetime.isocalendar() - Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The same as + Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The same as ``self.date().isocalendar()``. .. method:: datetime.isoformat(sep='T', timespec='auto') - Return a string representing the date and time in ISO 8601 format, - YYYY-MM-DDTHH:MM:SS.ffffff or, if :attr:`microsecond` is 0, - YYYY-MM-DDTHH:MM:SS + Return a string representing the date and time in ISO 8601 format: + + - ``YYYY-MM-DDTHH:MM:SS.ffffff``, if :attr:`microsecond` is not 0 + - ``YYYY-MM-DDTHH:MM:SS``, if :attr:`microsecond` is 0 If :meth:`utcoffset` does not return ``None``, a string is appended, giving the UTC offset: - YYYY-MM-DDTHH:MM:SS.ffffff+HH:MM[:SS[.ffffff]] or, if :attr:`microsecond` - is 0 YYYY-MM-DDTHH:MM:SS+HH:MM[:SS[.ffffff]]. + + - ``YYYY-MM-DDTHH:MM:SS.ffffff+HH:MM[:SS[.ffffff]]``, if :attr:`microsecond` + is not 0 + - ``YYYY-MM-DDTHH:MM:SS+HH:MM[:SS[.ffffff]]``, if :attr:`microsecond` is 0 + + Examples:: + + >>> from datetime import datetime, timezone + >>> datetime(2019, 5, 18, 15, 17, 8, 132263).isoformat() + '2019-05-18T15:17:08.132263' + >>> datetime(2019, 5, 18, 15, 17, tzinfo=timezone.utc).isoformat() + '2019-05-18T15:17:00+00:00' The optional argument *sep* (default ``'T'``) is a one-character separator, - placed between the date and time portions of the result. For example, + placed between the date and time portions of the result. For example:: >>> from datetime import tzinfo, timedelta, datetime >>> class TZ(tzinfo): - ... def utcoffset(self, dt): return timedelta(minutes=-399) + ... """A time zone with an arbitrary, constant -06:39 offset.""" + ... def utcoffset(self, dt): + ... return timedelta(hours=-6, minutes=-39) ... >>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ') '2002-12-25 00:00:00-06:39' + >>> datetime(2009, 11, 27, microsecond=100, tzinfo=TZ()).isoformat() + '2009-11-27T00:00:00.000100-06:39' The optional argument *timespec* specifies the number of additional components of the time to include (the default is ``'auto'``). @@ -1259,19 +1445,19 @@ Instance methods: - ``'auto'``: Same as ``'seconds'`` if :attr:`microsecond` is 0, same as ``'microseconds'`` otherwise. - - ``'hours'``: Include the :attr:`hour` in the two-digit HH format. - - ``'minutes'``: Include :attr:`hour` and :attr:`minute` in HH:MM format. + - ``'hours'``: Include the :attr:`hour` in the two-digit ``HH`` format. + - ``'minutes'``: Include :attr:`hour` and :attr:`minute` in ``HH:MM`` format. - ``'seconds'``: Include :attr:`hour`, :attr:`minute`, and :attr:`second` - in HH:MM:SS format. + in ``HH:MM:SS`` format. - ``'milliseconds'``: Include full time, but truncate fractional second - part to milliseconds. HH:MM:SS.sss format. - - ``'microseconds'``: Include full time in HH:MM:SS.ffffff format. + part to milliseconds. ``HH:MM:SS.sss`` format. + - ``'microseconds'``: Include full time in ``HH:MM:SS.ffffff`` format. .. note:: Excluded time components are truncated, not rounded. - :exc:`ValueError` will be raised on an invalid *timespec* argument. + :exc:`ValueError` will be raised on an invalid *timespec* argument:: >>> from datetime import datetime @@ -1293,48 +1479,64 @@ Instance methods: .. method:: datetime.ctime() - Return a string representing the date and time, for example ``datetime(2002, 12, - 4, 20, 30, 40).ctime() == 'Wed Dec 4 20:30:40 2002'``. ``d.ctime()`` is - equivalent to ``time.ctime(time.mktime(d.timetuple()))`` on platforms where the - native C :c:func:`ctime` function (which :func:`time.ctime` invokes, but which - :meth:`datetime.ctime` does not invoke) conforms to the C standard. + Return a string representing the date and time:: + + >>> from datetime import datetime + >>> datetime(2002, 12, 4, 20, 30, 40).ctime() + 'Wed Dec 4 20:30:40 2002' + + The output string will *not* include time zone information, regardless + of whether the input is aware or naive. + ``d.ctime()`` is equivalent to:: + + time.ctime(time.mktime(d.timetuple())) + + on platforms where the native C :c:func:`ctime` function + (which :func:`time.ctime` invokes, but which + :meth:`datetime.ctime` does not invoke) conforms to the C standard. .. method:: datetime.strftime(format) Return a string representing the date and time, controlled by an explicit format - string. For a complete list of formatting directives, see + string. For a complete list of formatting directives, see :ref:`strftime-strptime-behavior`. .. method:: datetime.__format__(format) - Same as :meth:`.datetime.strftime`. This makes it possible to specify a format + Same as :meth:`.datetime.strftime`. This makes it possible to specify a format string for a :class:`.datetime` object in :ref:`formatted string - literals ` and when using :meth:`str.format`. For a + literals ` and when using :meth:`str.format`. For a complete list of formatting directives, see :ref:`strftime-strptime-behavior`. +Examples of Usage: :class:`.datetime` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Examples of working with datetime objects: +Examples of working with :class:`~datetime.datetime` objects: .. doctest:: - >>> from datetime import datetime, date, time + >>> from datetime import datetime, date, time, timezone + >>> # Using datetime.combine() >>> d = date(2005, 7, 14) >>> t = time(12, 30) >>> datetime.combine(d, t) datetime.datetime(2005, 7, 14, 12, 30) - >>> # Using datetime.now() or datetime.utcnow() + + >>> # Using datetime.now() >>> datetime.now() # doctest: +SKIP datetime.datetime(2007, 12, 6, 16, 29, 43, 79043) # GMT +1 - >>> datetime.utcnow() # doctest: +SKIP - datetime.datetime(2007, 12, 6, 15, 29, 43, 79060) + >>> datetime.now(timezone.utc) # doctest: +SKIP + datetime.datetime(2007, 12, 6, 15, 29, 43, 79060, tzinfo=datetime.timezone.utc) + >>> # Using datetime.strptime() >>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") >>> dt datetime.datetime(2006, 11, 21, 16, 30) + >>> # Using datetime.timetuple() to get tuple of all attributes >>> tt = dt.timetuple() >>> for it in tt: # doctest: +SKIP @@ -1349,6 +1551,7 @@ Examples of working with datetime objects: 1 # weekday (0 = Monday) 325 # number of days since 1st January -1 # dst - method tzinfo.dst() returned None + >>> # Date in ISO format >>> ic = dt.isocalendar() >>> for it in ic: # doctest: +SKIP @@ -1357,89 +1560,95 @@ Examples of working with datetime objects: 2006 # ISO year 47 # ISO week 2 # ISO weekday - >>> # Formatting datetime + + >>> # Formatting a datetime >>> dt.strftime("%A, %d. %B %Y %I:%M%p") 'Tuesday, 21. November 2006 04:30PM' >>> 'The {1} is {0:%d}, the {2} is {0:%B}, the {3} is {0:%I:%M%p}.'.format(dt, "day", "month", "time") 'The day is 21, the month is November, the time is 04:30PM.' -Using datetime with tzinfo: - - >>> from datetime import timedelta, datetime, tzinfo, timezone - >>> class KabulTz(tzinfo): - ... # Kabul used +4 until 1945, when they moved to +4:30 - ... UTC_MOVE_DATE = datetime(1944, 12, 31, 20, tzinfo=timezone.utc) - ... def utcoffset(self, dt): - ... if dt.year < 1945: - ... return timedelta(hours=4) - ... elif (1945, 1, 1, 0, 0) <= dt.timetuple()[:5] < (1945, 1, 1, 0, 30): - ... # If dt falls in the imaginary range, use fold to decide how - ... # to resolve. See PEP495 - ... return timedelta(hours=4, minutes=(30 if dt.fold else 0)) - ... else: - ... return timedelta(hours=4, minutes=30) - ... - ... def fromutc(self, dt): - ... # A custom implementation is required for fromutc as - ... # the input to this function is a datetime with utc values - ... # but with a tzinfo set to self - ... # See datetime.astimezone or fromtimestamp - ... - ... # Follow same validations as in datetime.tzinfo - ... if not isinstance(dt, datetime): - ... raise TypeError("fromutc() requires a datetime argument") - ... if dt.tzinfo is not self: - ... raise ValueError("dt.tzinfo is not self") - ... - ... if dt.replace(tzinfo=timezone.utc) >= self.UTC_MOVE_DATE: - ... return dt + timedelta(hours=4, minutes=30) - ... else: - ... return dt + timedelta(hours=4) - ... - ... def dst(self, dt): - ... return timedelta(0) - ... - ... def tzname(self, dt): - ... if dt >= self.UTC_MOVE_DATE: - ... return "+04:30" - ... else: - ... return "+04" - ... - ... def __repr__(self): - ... return f"{self.__class__.__name__}()" - ... - >>> tz1 = KabulTz() - >>> # Datetime before the change - >>> dt1 = datetime(1900, 11, 21, 16, 30, tzinfo=tz1) - >>> print(dt1.utcoffset()) - 4:00:00 - >>> # Datetime after the change - >>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=tz1) - >>> print(dt2.utcoffset()) - 4:30:00 - >>> # Convert datetime to another time zone - >>> dt3 = dt2.astimezone(timezone.utc) - >>> dt3 - datetime.datetime(2006, 6, 14, 8, 30, tzinfo=datetime.timezone.utc) - >>> dt2 - datetime.datetime(2006, 6, 14, 13, 0, tzinfo=KabulTz()) - >>> dt2.utctimetuple() == dt3.utctimetuple() - True - - +The example below defines a :class:`tzinfo` subclass capturing time zone +information for Kabul, Afghanistan, which used +4 UTC until 1945 +and then +4:30 UTC thereafter:: + + from datetime import timedelta, datetime, tzinfo, timezone + + class KabulTz(tzinfo): + # Kabul used +4 until 1945, when they moved to +4:30 + UTC_MOVE_DATE = datetime(1944, 12, 31, 20, tzinfo=timezone.utc) + + def utcoffset(self, dt): + if dt.year < 1945: + return timedelta(hours=4) + elif (1945, 1, 1, 0, 0) <= dt.timetuple()[:5] < (1945, 1, 1, 0, 30): + # An ambiguous ("imaginary") half-hour range representing + # a 'fold' in time due to the shift from +4 to +4:30. + # If dt falls in the imaginary range, use fold to decide how + # to resolve. See PEP495. + return timedelta(hours=4, minutes=(30 if dt.fold else 0)) + else: + return timedelta(hours=4, minutes=30) + + def fromutc(self, dt): + # Follow same validations as in datetime.tzinfo + if not isinstance(dt, datetime): + raise TypeError("fromutc() requires a datetime argument") + if dt.tzinfo is not self: + raise ValueError("dt.tzinfo is not self") + + # A custom implementation is required for fromutc as + # the input to this function is a datetime with utc values + # but with a tzinfo set to self. + # See datetime.astimezone or fromtimestamp. + if dt.replace(tzinfo=timezone.utc) >= self.UTC_MOVE_DATE: + return dt + timedelta(hours=4, minutes=30) + else: + return dt + timedelta(hours=4) + + def dst(self, dt): + # Kabul does not observe daylight saving time. + return timedelta(0) + + def tzname(self, dt): + if dt >= self.UTC_MOVE_DATE: + return "+04:30" + return "+04" + +Usage of ``KabulTz`` from above:: + + >>> tz1 = KabulTz() + + >>> # Datetime before the change + >>> dt1 = datetime(1900, 11, 21, 16, 30, tzinfo=tz1) + >>> print(dt1.utcoffset()) + 4:00:00 + + >>> # Datetime after the change + >>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=tz1) + >>> print(dt2.utcoffset()) + 4:30:00 + + >>> # Convert datetime to another time zone + >>> dt3 = dt2.astimezone(timezone.utc) + >>> dt3 + datetime.datetime(2006, 6, 14, 8, 30, tzinfo=datetime.timezone.utc) + >>> dt2 + datetime.datetime(2006, 6, 14, 13, 0, tzinfo=KabulTz()) + >>> dt2 == dt3 + True .. _datetime-time: :class:`.time` Objects ---------------------- -A time object represents a (local) time of day, independent of any particular +A :class:`time` object represents a (local) time of day, independent of any particular day, and subject to adjustment via a :class:`tzinfo` object. .. class:: time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0) - All arguments are optional. *tzinfo* may be ``None``, or an instance of a - :class:`tzinfo` subclass. The remaining arguments may be integers, in the + All arguments are optional. *tzinfo* may be ``None``, or an instance of a + :class:`tzinfo` subclass. The remaining arguments must be integers in the following ranges: * ``0 <= hour < 24``, @@ -1448,7 +1657,7 @@ day, and subject to adjustment via a :class:`tzinfo` object. * ``0 <= microsecond < 1000000``, * ``fold in [0, 1]``. - If an argument outside those ranges is given, :exc:`ValueError` is raised. All + If an argument outside those ranges is given, :exc:`ValueError` is raised. All default to ``0`` except *tzinfo*, which defaults to :const:`None`. Class attributes: @@ -1501,7 +1710,7 @@ Instance attributes (read-only): .. attribute:: time.fold - In ``[0, 1]``. Used to disambiguate wall times during a repeated interval. (A + In ``[0, 1]``. Used to disambiguate wall times during a repeated interval. (A repeated interval occurs when clocks are rolled back at the end of daylight saving time or when the UTC offset for the current zone is decreased for political reasons.) The value 0 (1) represents the earlier (later) of the two moments with the same wall @@ -1509,38 +1718,32 @@ Instance attributes (read-only): .. versionadded:: 3.6 +:class:`.time` objects support comparison of :class:`.time` to :class:`.time`, +where *a* is considered less +than *b* when *a* precedes *b* in time. If one comparand is naive and the other +is aware, :exc:`TypeError` is raised if an order comparison is attempted. For equality +comparisons, naive instances are never equal to aware instances. -Supported operations: - -* comparison of :class:`.time` to :class:`.time`, where *a* is considered less - than *b* when *a* precedes *b* in time. If one comparand is naive and the other - is aware, :exc:`TypeError` is raised if an order comparison is attempted. For equality - comparisons, naive instances are never equal to aware instances. - - If both comparands are aware, and have - the same :attr:`~time.tzinfo` attribute, the common :attr:`~time.tzinfo` attribute is - ignored and the base times are compared. If both comparands are aware and - have different :attr:`~time.tzinfo` attributes, the comparands are first adjusted by - subtracting their UTC offsets (obtained from ``self.utcoffset()``). In order - to stop mixed-type comparisons from falling back to the default comparison by - object address, when a :class:`.time` object is compared to an object of a - different type, :exc:`TypeError` is raised unless the comparison is ``==`` or - ``!=``. The latter cases return :const:`False` or :const:`True`, respectively. - - .. versionchanged:: 3.3 - Equality comparisons between naive and aware :class:`~datetime.time` instances - don't raise :exc:`TypeError`. +If both comparands are aware, and have +the same :attr:`~time.tzinfo` attribute, the common :attr:`~time.tzinfo` attribute is +ignored and the base times are compared. If both comparands are aware and +have different :attr:`~time.tzinfo` attributes, the comparands are first adjusted by +subtracting their UTC offsets (obtained from ``self.utcoffset()``). In order +to stop mixed-type comparisons from falling back to the default comparison by +object address, when a :class:`.time` object is compared to an object of a +different type, :exc:`TypeError` is raised unless the comparison is ``==`` or +``!=``. The latter cases return :const:`False` or :const:`True`, respectively. -* hash, use as dict key +.. versionchanged:: 3.3 + Equality comparisons between aware and naive :class:`~datetime.time` instances + don't raise :exc:`TypeError`. -* efficient pickling - -In boolean contexts, a :class:`.time` object is always considered to be true. +In Boolean contexts, a :class:`.time` object is always considered to be true. .. versionchanged:: 3.5 Before Python 3.5, a :class:`.time` object was considered to be false if it - represented midnight in UTC. This behavior was considered obscure and - error-prone and has been removed in Python 3.5. See :issue:`13936` for full + represented midnight in UTC. This behavior was considered obscure and + error-prone and has been removed in Python 3.5. See :issue:`13936` for full details. @@ -1548,16 +1751,30 @@ 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(s) ``HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]``. + 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: + + .. 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`. - .. caution:: + Examples:: - This does not support parsing arbitrary ISO 8601 strings - it is only intended - as the inverse operation of :meth:`time.isoformat`. + >>> from datetime import time + >>> time.fromisoformat('04:23:01') + datetime.time(4, 23, 1) + >>> time.fromisoformat('04:23:01.000384') + 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))) - .. versionadded:: 3.7 + .. versionadded:: 3.7 Instance methods: @@ -1566,7 +1783,7 @@ Instance methods: microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0) Return a :class:`.time` with the same value, except for those attributes given - new values by whichever keyword arguments are specified. Note that + new values by whichever keyword arguments are specified. Note that ``tzinfo=None`` can be specified to create a naive :class:`.time` from an aware :class:`.time`, without conversion of the time data. @@ -1576,10 +1793,12 @@ Instance methods: .. method:: time.isoformat(timespec='auto') - Return a string representing the time in ISO 8601 format, HH:MM:SS.ffffff or, if - :attr:`microsecond` is 0, HH:MM:SS If :meth:`utcoffset` does not return ``None``, a - string is appended, giving the UTC offset: HH:MM:SS.ffffff+HH:MM[:SS[.ffffff]] - or, if self.microsecond is 0, HH:MM:SS+HH:MM[:SS[.ffffff]]. + Return a string representing the time in ISO 8601 format, one of: + + - ``HH:MM:SS.ffffff``, if :attr:`microsecond` is not 0 + - ``HH:MM:SS``, if :attr:`microsecond` is 0 + - ``HH:MM:SS.ffffff+HH:MM[:SS[.ffffff]]``, if :meth:`utcoffset` does not return ``None`` + - ``HH:MM:SS+HH:MM[:SS[.ffffff]]``, if :attr:`microsecond` is 0 and :meth:`utcoffset` does not return ``None`` The optional argument *timespec* specifies the number of additional components of the time to include (the default is ``'auto'``). @@ -1587,13 +1806,13 @@ Instance methods: - ``'auto'``: Same as ``'seconds'`` if :attr:`microsecond` is 0, same as ``'microseconds'`` otherwise. - - ``'hours'``: Include the :attr:`hour` in the two-digit HH format. - - ``'minutes'``: Include :attr:`hour` and :attr:`minute` in HH:MM format. + - ``'hours'``: Include the :attr:`hour` in the two-digit ``HH`` format. + - ``'minutes'``: Include :attr:`hour` and :attr:`minute` in ``HH:MM`` format. - ``'seconds'``: Include :attr:`hour`, :attr:`minute`, and :attr:`second` - in HH:MM:SS format. + in ``HH:MM:SS`` format. - ``'milliseconds'``: Include full time, but truncate fractional second - part to milliseconds. HH:MM:SS.sss format. - - ``'microseconds'``: Include full time in HH:MM:SS.ffffff format. + part to milliseconds. ``HH:MM:SS.sss`` format. + - ``'microseconds'``: Include full time in ``HH:MM:SS.ffffff`` format. .. note:: @@ -1601,6 +1820,7 @@ Instance methods: :exc:`ValueError` will be raised on an invalid *timespec* argument. + Example:: >>> from datetime import time >>> time(hour=12, minute=34, second=56, microsecond=123456).isoformat(timespec='minutes') @@ -1623,7 +1843,7 @@ Instance methods: .. method:: time.strftime(format) Return a string representing the time, controlled by an explicit format - string. For a complete list of formatting directives, see + string. For a complete list of formatting directives, see :ref:`strftime-strptime-behavior`. @@ -1631,7 +1851,7 @@ Instance methods: Same as :meth:`.time.strftime`. This makes it possible to specify a format string for a :class:`.time` object in :ref:`formatted string - literals ` and when using :meth:`str.format`. For a + literals ` and when using :meth:`str.format`. For a complete list of formatting directives, see :ref:`strftime-strptime-behavior`. @@ -1661,7 +1881,10 @@ Instance methods: ``self.tzinfo.tzname(None)``, or raises an exception if the latter doesn't return ``None`` or a string object. -Example: +Examples of Usage: :class:`.time` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Examples of working with a :class:`.time` object:: >>> from datetime import time, tzinfo, timedelta >>> class TZ1(tzinfo): @@ -1697,12 +1920,8 @@ Example: .. class:: tzinfo() This is an abstract base class, meaning that this class should not be - instantiated directly. You need to derive a concrete subclass, and (at least) - supply implementations of the standard :class:`tzinfo` methods needed by the - :class:`.datetime` methods you use. The :mod:`datetime` module supplies - a simple concrete subclass of :class:`tzinfo`, :class:`timezone`, which can represent - timezones with fixed offset from UTC such as UTC itself or North American EST and - EDT. + instantiated directly. Define a subclass of :class:`tzinfo` to capture + information about a particular time zone. An instance of (a concrete subclass of) :class:`tzinfo` can be passed to the constructors for :class:`.datetime` and :class:`.time` objects. The latter objects @@ -1710,28 +1929,35 @@ Example: supports methods revealing offset of local time from UTC, the name of the time zone, and DST offset, all relative to a date or time object passed to them. + You need to derive a concrete subclass, and (at least) + supply implementations of the standard :class:`tzinfo` methods needed by the + :class:`.datetime` methods you use. The :mod:`datetime` module provides + :class:`timezone`, a simple concrete subclass of :class:`tzinfo` which can + represent timezones with fixed offset from UTC such as UTC itself or North + American EST and EDT. + Special requirement for pickling: A :class:`tzinfo` subclass must have an - :meth:`__init__` method that can be called with no arguments, else it can be - pickled but possibly not unpickled again. This is a technical requirement that + :meth:`__init__` method that can be called with no arguments, otherwise it can be + pickled but possibly not unpickled again. This is a technical requirement that may be relaxed in the future. A concrete subclass of :class:`tzinfo` may need to implement the following - methods. Exactly which methods are needed depends on the uses made of aware - :mod:`datetime` objects. If in doubt, simply implement all of them. + methods. Exactly which methods are needed depends on the uses made of aware + :mod:`datetime` objects. If in doubt, simply implement all of them. .. method:: tzinfo.utcoffset(dt) Return offset of local time from UTC, as a :class:`timedelta` object that is - positive east of UTC. If local time is - west of UTC, this should be negative. Note that this is intended to be the - total offset from UTC; for example, if a :class:`tzinfo` object represents both - time zone and DST adjustments, :meth:`utcoffset` should return their sum. If - the UTC offset isn't known, return ``None``. Else the value returned must be a - :class:`timedelta` object strictly between ``-timedelta(hours=24)`` and - ``timedelta(hours=24)`` (the magnitude of the offset must be less - than one day). Most implementations of :meth:`utcoffset` will probably look - like one of these two:: + positive east of UTC. If local time is west of UTC, this should be negative. + + This represents the *total* offset from UTC; for example, if a + :class:`tzinfo` object represents both time zone and DST adjustments, + :meth:`utcoffset` should return their sum. If the UTC offset isn't known, + return ``None``. Else the value returned must be a :class:`timedelta` object + strictly between ``-timedelta(hours=24)`` and ``timedelta(hours=24)`` + (the magnitude of the offset must be less than one day). Most implementations + of :meth:`utcoffset` will probably look like one of these two:: return CONSTANT # fixed-offset class return CONSTANT + self.dst(dt) # daylight-aware class @@ -1750,12 +1976,14 @@ Example: Return the daylight saving time (DST) adjustment, as a :class:`timedelta` object or - ``None`` if DST information isn't known. Return ``timedelta(0)`` if DST is not - in effect. If DST is in effect, return the offset as a :class:`timedelta` object + ``None`` if DST information isn't known. + + Return ``timedelta(0)`` if DST is not in effect. + If DST is in effect, return the offset as a :class:`timedelta` object (see :meth:`utcoffset` for details). Note that DST offset, if applicable, has already been added to the UTC offset returned by :meth:`utcoffset`, so there's no need to consult :meth:`dst` unless you're interested in obtaining DST info - separately. For example, :meth:`datetime.timetuple` calls its :attr:`~.datetime.tzinfo` + separately. For example, :meth:`datetime.timetuple` calls its :attr:`~.datetime.tzinfo` attribute's :meth:`dst` method to determine how the :attr:`tm_isdst` flag should be set, and :meth:`tzinfo.fromutc` calls :meth:`dst` to account for DST changes when crossing time zones. @@ -1768,9 +1996,9 @@ Example: must return the same result for every :class:`.datetime` *dt* with ``dt.tzinfo == tz`` For sane :class:`tzinfo` subclasses, this expression yields the time zone's "standard offset", which should not depend on the date or the time, but - only on geographic location. The implementation of :meth:`datetime.astimezone` + only on geographic location. The implementation of :meth:`datetime.astimezone` relies on this, but cannot detect violations; it's the programmer's - responsibility to ensure it. If a :class:`tzinfo` subclass cannot guarantee + responsibility to ensure it. If a :class:`tzinfo` subclass cannot guarantee this, it may be able to override the default implementation of :meth:`tzinfo.fromutc` to work correctly with :meth:`astimezone` regardless. @@ -1780,12 +2008,12 @@ Example: # a fixed-offset class: doesn't account for DST return timedelta(0) - or :: + or:: def dst(self, dt): # Code to set dston and dstoff to the time zone's DST # transition times based on the input dt.year, and expressed - # in standard local time. Then + # in standard local time. if dston <= dt.replace(tzinfo=None) < dstoff: return timedelta(hours=1) @@ -1802,9 +2030,9 @@ Example: Return the time zone name corresponding to the :class:`.datetime` object *dt*, as a string. Nothing about string names is defined by the :mod:`datetime` module, - and there's no requirement that it mean anything in particular. For example, + and there's no requirement that it mean anything in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", "US/Eastern", "America/New York" are all - valid replies. Return ``None`` if a string name isn't known. Note that this is + valid replies. Return ``None`` if a string name isn't known. Note that this is a method rather than a fixed string primarily because some :class:`tzinfo` subclasses will wish to return different names depending on the specific value of *dt* passed, especially if the :class:`tzinfo` class is accounting for @@ -1814,20 +2042,20 @@ Example: These methods are called by a :class:`.datetime` or :class:`.time` object, in -response to their methods of the same names. A :class:`.datetime` object passes +response to their methods of the same names. A :class:`.datetime` object passes itself as the argument, and a :class:`.time` object passes ``None`` as the -argument. A :class:`tzinfo` subclass's methods should therefore be prepared to +argument. A :class:`tzinfo` subclass's methods should therefore be prepared to accept a *dt* argument of ``None``, or of class :class:`.datetime`. When ``None`` is passed, it's up to the class designer to decide the best -response. For example, returning ``None`` is appropriate if the class wishes to -say that time objects don't participate in the :class:`tzinfo` protocols. It +response. For example, returning ``None`` is appropriate if the class wishes to +say that time objects don't participate in the :class:`tzinfo` protocols. It may be more useful for ``utcoffset(None)`` to return the standard UTC offset, as there is no other convention for discovering the standard offset. When a :class:`.datetime` object is passed in response to a :class:`.datetime` -method, ``dt.tzinfo`` is the same object as *self*. :class:`tzinfo` methods can -rely on this, unless user code calls :class:`tzinfo` methods directly. The +method, ``dt.tzinfo`` is the same object as *self*. :class:`tzinfo` methods can +rely on this, unless user code calls :class:`tzinfo` methods directly. The intent is that the :class:`tzinfo` methods interpret *dt* as being in local time, and not need worry about objects in other timezones. @@ -1837,16 +2065,16 @@ There is one more :class:`tzinfo` method that a subclass may wish to override: .. method:: tzinfo.fromutc(dt) This is called from the default :class:`datetime.astimezone()` - implementation. When called from that, ``dt.tzinfo`` is *self*, and *dt*'s - date and time data are to be viewed as expressing a UTC time. The purpose + implementation. When called from that, ``dt.tzinfo`` is *self*, and *dt*'s + date and time data are to be viewed as expressing a UTC time. The purpose of :meth:`fromutc` is to adjust the date and time data, returning an equivalent datetime in *self*'s local time. Most :class:`tzinfo` subclasses should be able to inherit the default - :meth:`fromutc` implementation without problems. It's strong enough to handle + :meth:`fromutc` implementation without problems. It's strong enough to handle fixed-offset time zones, and time zones accounting for both standard and daylight time, and the latter even if the DST transition times differ in - different years. An example of a time zone the default :meth:`fromutc` + different years. An example of a time zone the default :meth:`fromutc` implementation may not handle correctly in all cases is one where the standard offset (from UTC) depends on the specific date and time passed, which can happen for political reasons. The default implementations of :meth:`astimezone` and @@ -1879,7 +2107,7 @@ In the following :download:`tzinfo_examples.py Note that there are unavoidable subtleties twice per year in a :class:`tzinfo` subclass accounting for both standard and daylight time, at the DST transition -points. For concreteness, consider US Eastern (UTC -0500), where EDT begins the +points. For concreteness, consider US Eastern (UTC -0500), where EDT begins the minute after 1:59 (EST) on the second Sunday in March, and ends the minute after 1:59 (EDT) on the first Sunday in November:: @@ -1892,9 +2120,9 @@ minute after 1:59 (EST) on the second Sunday in March, and ends the minute after end 23:MM 0:MM 1:MM 1:MM 2:MM 3:MM When DST starts (the "start" line), the local wall clock leaps from 1:59 to -3:00. A wall time of the form 2:MM doesn't really make sense on that day, so +3:00. A wall time of the form 2:MM doesn't really make sense on that day, so ``astimezone(Eastern)`` won't deliver a result with ``hour == 2`` on the day DST -begins. For example, at the Spring forward transition of 2016, we get +begins. For example, at the Spring forward transition of 2016, we get:: >>> from datetime import datetime, timezone >>> from tzinfo_examples import HOUR, Eastern @@ -1912,14 +2140,14 @@ begins. For example, at the Spring forward transition of 2016, we get When DST ends (the "end" line), there's a potentially worse problem: there's an hour that can't be spelled unambiguously in local wall time: the last hour of -daylight time. In Eastern, that's times of the form 5:MM UTC on the day -daylight time ends. The local wall clock leaps from 1:59 (daylight time) back +daylight time. In Eastern, that's times of the form 5:MM UTC on the day +daylight time ends. The local wall clock leaps from 1:59 (daylight time) back to 1:00 (standard time) again. Local times of the form 1:MM are ambiguous. :meth:`astimezone` mimics the local clock's behavior by mapping two adjacent UTC -hours into the same local hour then. In the Eastern example, UTC times of the +hours into the same local hour then. In the Eastern example, UTC times of the form 5:MM and 6:MM both map to 1:MM when converted to Eastern, but earlier times have the :attr:`~datetime.fold` attribute set to 0 and the later times have it set to 1. -For example, at the Fall back transition of 2016, we get +For example, at the Fall back transition of 2016, we get:: >>> u0 = datetime(2016, 11, 6, 4, tzinfo=timezone.utc) >>> for i in range(4): @@ -1932,7 +2160,7 @@ For example, at the Fall back transition of 2016, we get 06:00:00 UTC = 01:00:00 EST 1 07:00:00 UTC = 02:00:00 EST 0 -Note that the :class:`datetime` instances that differ only by the value of the +Note that the :class:`.datetime` instances that differ only by the value of the :attr:`~datetime.fold` attribute are considered equal in comparisons. Applications that can't bear wall-time ambiguities should explicitly check the @@ -1944,15 +2172,17 @@ only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)). .. seealso:: `dateutil.tz `_ - The standard library has :class:`timezone` class for handling arbitrary - fixed offsets from UTC and :attr:`timezone.utc` as UTC timezone instance. + The :mod:`datetime` module has a basic :class:`timezone` class (for + handling arbitrary fixed offsets from UTC) and its :attr:`timezone.utc` + attribute (a UTC timezone instance). - *dateutil.tz* library brings the *IANA timezone database* (also known as the - Olson database) to Python and its usage is recommended. + *dateutil.tz* library brings the *IANA timezone database* + (also known as the Olson database) to Python, and its usage is + recommended. `IANA timezone database `_ - The Time Zone Database (often called tz, tzdata or zoneinfo) contains code and - data that represent the history of local time for many representative + The Time Zone Database (often called tz, tzdata or zoneinfo) contains code + and data that represent the history of local time for many representative locations around the globe. It is updated periodically to reflect changes made by political bodies to time zone boundaries, UTC offsets, and daylight-saving rules. @@ -1965,20 +2195,21 @@ only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)). The :class:`timezone` class is a subclass of :class:`tzinfo`, each instance of which represents a timezone defined by a fixed offset from -UTC. Note that objects of this class cannot be used to represent -timezone information in the locations where different offsets are used -in different days of the year or where historical changes have been -made to civil time. +UTC. + +Objects of this class cannot be used to represent timezone information in the +locations where different offsets are used in different days of the year or +where historical changes have been made to civil time. .. class:: timezone(offset, name=None) The *offset* argument must be specified as a :class:`timedelta` - object representing the difference between the local time and UTC. It must + object representing the difference between the local time and UTC. It must be strictly between ``-timedelta(hours=24)`` and ``timedelta(hours=24)``, otherwise :exc:`ValueError` is raised. - The *name* argument is optional. If specified it must be a string that + The *name* argument is optional. If specified it must be a string that will be used as the value returned by the :meth:`datetime.tzname` method. .. versionadded:: 3.2 @@ -1990,9 +2221,10 @@ made to civil time. .. method:: timezone.utcoffset(dt) Return the fixed value specified when the :class:`timezone` instance is - constructed. The *dt* argument is ignored. The return value is a - :class:`timedelta` instance equal to the difference between the - local time and UTC. + constructed. + + The *dt* argument is ignored. The return value is a :class:`timedelta` + instance equal to the difference between the local time and UTC. .. versionchanged:: 3.7 The UTC offset is not restricted to a whole number of minutes. @@ -2000,16 +2232,17 @@ made to civil time. .. method:: timezone.tzname(dt) Return the fixed value specified when the :class:`timezone` instance - is constructed. If *name* is not provided in the constructor, the - name returned by ``tzname(dt)`` is generated from the value of the - ``offset`` as follows. If *offset* is ``timedelta(0)``, the name - is "UTC", otherwise it is a string 'UTC±HH:MM', where ± is the sign - of ``offset``, HH and MM are two digits of ``offset.hours`` and - ``offset.minutes`` respectively. + is constructed. + + If *name* is not provided in the constructor, the name returned by + ``tzname(dt)`` is generated from the value of the ``offset`` as follows. If + *offset* is ``timedelta(0)``, the name is "UTC", otherwise it is a string in + the format ``UTC±HH:MM``, where ± is the sign of ``offset``, HH and MM are + two digits of ``offset.hours`` and ``offset.minutes`` respectively. .. versionchanged:: 3.6 - Name generated from ``offset=timedelta(0)`` is now plain 'UTC', not - 'UTC+00:00'. + Name generated from ``offset=timedelta(0)`` is now plain `'UTC'`, not + ``'UTC+00:00'``. .. method:: timezone.dst(dt) @@ -2018,7 +2251,7 @@ made to civil time. .. method:: timezone.fromutc(dt) - Return ``dt + offset``. The *dt* argument must be an aware + Return ``dt + offset``. The *dt* argument must be an aware :class:`.datetime` instance, with ``tzinfo`` set to ``self``. Class attributes: @@ -2038,43 +2271,33 @@ Class attributes: :class:`date`, :class:`.datetime`, and :class:`.time` objects all support a ``strftime(format)`` method, to create a string representing the time under the -control of an explicit format string. Broadly speaking, ``d.strftime(fmt)`` -acts like the :mod:`time` module's ``time.strftime(fmt, d.timetuple())`` -although not all objects support a :meth:`timetuple` method. +control of an explicit format string. Conversely, the :meth:`datetime.strptime` class method creates a :class:`.datetime` object from a string representing a date and time and a -corresponding format string. ``datetime.strptime(date_string, format)`` is -equivalent to ``datetime(*(time.strptime(date_string, format)[0:6]))``, except -when the format includes sub-second components or timezone offset information, -which are supported in ``datetime.strptime`` but are discarded by ``time.strptime``. +corresponding format string. -For :class:`.time` objects, the format codes for year, month, and day should not -be used, as time objects have no such values. If they're used anyway, ``1900`` -is substituted for the year, and ``1`` for the month and day. - -For :class:`date` objects, the format codes for hours, minutes, seconds, and -microseconds should not be used, as :class:`date` objects have no such -values. If they're used anyway, ``0`` is substituted for them. +The table below provides a high-level comparison of :meth:`strftime` +versus :meth:`strptime`: -For the :meth:`datetime.strptime` class method, the default value is ``1900-01-01T00:00:00.000``: -any components not specified in the format string will be pulled from the default value. [#]_ ++----------------+--------------------------------------------------------+------------------------------------------------------------------------------+ +| | ``strftime`` | ``strptime`` | ++================+========================================================+==============================================================================+ +| Usage | Convert object to a string according to a given format | Parse a string into a :class:`.datetime` object given a corresponding format | ++----------------+--------------------------------------------------------+------------------------------------------------------------------------------+ +| Type of method | Instance method | Class method | ++----------------+--------------------------------------------------------+------------------------------------------------------------------------------+ +| Method of | :class:`date`; :class:`.datetime`; :class:`.time` | :class:`.datetime` | ++----------------+--------------------------------------------------------+------------------------------------------------------------------------------+ +| Signature | ``strftime(format)`` | ``strptime(date_string, format)`` | ++----------------+--------------------------------------------------------+------------------------------------------------------------------------------+ -The full set of format codes supported varies across platforms, because Python -calls the platform C library's :func:`strftime` function, and platform -variations are common. To see the full set of format codes supported on your -platform, consult the :manpage:`strftime(3)` documentation. -For the same reason, handling of format strings containing Unicode code points -that can't be represented in the charset of the current locale is also -platform-dependent. On some platforms such code points are preserved intact in -the output, while on others ``strftime`` may raise :exc:`UnicodeError` or return -an empty string instead. +:meth:`strftime` and :meth:`strptime` Format Codes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following is a list of all the format codes that the C standard (1989 -version) requires, and these work on all platforms with a standard C -implementation. Note that the 1999 version of the C standard added additional -format codes. +The following is a list of all the format codes that the 1989 C standard +requires, and these work on all platforms with a standard C implementation. +-----------+--------------------------------+------------------------+-------+ | Directive | Meaning | Example | Notes | @@ -2093,7 +2316,7 @@ format codes. | | where 0 is Sunday and 6 is | | | | | Saturday. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%d`` | Day of the month as a | 01, 02, ..., 31 | | +| ``%d`` | Day of the month as a | 01, 02, ..., 31 | \(9) | | | zero-padded decimal number. | | | +-----------+--------------------------------+------------------------+-------+ | ``%b`` | Month as locale's abbreviated || Jan, Feb, ..., Dec | \(1) | @@ -2106,55 +2329,55 @@ format codes. | | || Januar, Februar, ..., | | | | | Dezember (de_DE) | | +-----------+--------------------------------+------------------------+-------+ -| ``%m`` | Month as a zero-padded | 01, 02, ..., 12 | | +| ``%m`` | Month as a zero-padded | 01, 02, ..., 12 | \(9) | | | decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%y`` | Year without century as a | 00, 01, ..., 99 | | +| ``%y`` | Year without century as a | 00, 01, ..., 99 | \(9) | | | zero-padded decimal number. | | | +-----------+--------------------------------+------------------------+-------+ | ``%Y`` | Year with century as a decimal | 0001, 0002, ..., 2013, | \(2) | | | number. | 2014, ..., 9998, 9999 | | +-----------+--------------------------------+------------------------+-------+ -| ``%H`` | Hour (24-hour clock) as a | 00, 01, ..., 23 | | +| ``%H`` | Hour (24-hour clock) as a | 00, 01, ..., 23 | \(9) | | | zero-padded decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%I`` | Hour (12-hour clock) as a | 01, 02, ..., 12 | | +| ``%I`` | Hour (12-hour clock) as a | 01, 02, ..., 12 | \(9) | | | zero-padded decimal number. | | | +-----------+--------------------------------+------------------------+-------+ | ``%p`` | Locale's equivalent of either || AM, PM (en_US); | \(1), | | | AM or PM. || am, pm (de_DE) | \(3) | +-----------+--------------------------------+------------------------+-------+ -| ``%M`` | Minute as a zero-padded | 00, 01, ..., 59 | | +| ``%M`` | Minute as a zero-padded | 00, 01, ..., 59 | \(9) | | | decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%S`` | Second as a zero-padded | 00, 01, ..., 59 | \(4) | -| | decimal number. | | | +| ``%S`` | Second as a zero-padded | 00, 01, ..., 59 | \(4), | +| | decimal number. | | \(9) | +-----------+--------------------------------+------------------------+-------+ | ``%f`` | Microsecond as a decimal | 000000, 000001, ..., | \(5) | | | number, zero-padded on the | 999999 | | | | left. | | | +-----------+--------------------------------+------------------------+-------+ | ``%z`` | UTC offset in the form | (empty), +0000, | \(6) | -| | ±HHMM[SS[.ffffff]] (empty | -0400, +1030, | | +| | ``±HHMM[SS[.ffffff]]`` (empty | -0400, +1030, | | | | string if the object is | +063415, | | | | naive). | -030712.345216 | | +-----------+--------------------------------+------------------------+-------+ | ``%Z`` | Time zone name (empty string | (empty), UTC, EST, CST | | | | if the object is naive). | | | +-----------+--------------------------------+------------------------+-------+ -| ``%j`` | Day of the year as a | 001, 002, ..., 366 | | +| ``%j`` | Day of the year as a | 001, 002, ..., 366 | \(9) | | | zero-padded decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%U`` | Week number of the year | 00, 01, ..., 53 | \(7) | -| | (Sunday as the first day of | | | +| ``%U`` | Week number of the year | 00, 01, ..., 53 | \(7), | +| | (Sunday as the first day of | | \(9) | | | the week) as a zero padded | | | | | decimal number. All days in a | | | | | new year preceding the first | | | | | Sunday are considered to be in | | | | | week 0. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%W`` | Week number of the year | 00, 01, ..., 53 | \(7) | -| | (Monday as the first day of | | | +| ``%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 | | | @@ -2177,11 +2400,7 @@ format codes. +-----------+--------------------------------+------------------------+-------+ Several additional directives not required by the C89 standard are included for -convenience. These parameters all correspond to ISO 8601 date values. 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 -with the year and week number directives above. Calling :meth:`strptime` with -incomplete or ambiguous ISO 8601 directives will raise a :exc:`ValueError`. +convenience. These parameters all correspond to ISO 8601 date values. +-----------+--------------------------------+------------------------+-------+ | Directive | Meaning | Example | Notes | @@ -2194,16 +2413,59 @@ incomplete or ambiguous ISO 8601 directives will raise a :exc:`ValueError`. | ``%u`` | ISO 8601 weekday as a decimal | 1, 2, ..., 7 | | | | number where 1 is Monday. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%V`` | ISO 8601 week as a decimal | 01, 02, ..., 53 | \(8) | -| | number with Monday as | | | +| ``%V`` | ISO 8601 week as a decimal | 01, 02, ..., 53 | \(8), | +| | number with Monday as | | \(9) | | | the first day of the week. | | | | | Week 01 is the week containing | | | | | Jan 4. | | | +-----------+--------------------------------+------------------------+-------+ +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 +with the year and week number directives above. Calling :meth:`strptime` with +incomplete or ambiguous ISO 8601 directives will raise a :exc:`ValueError`. + +The full set of format codes supported varies across platforms, because Python +calls the platform C library's :func:`strftime` function, and platform +variations are common. To see the full set of format codes supported on your +platform, consult the :manpage:`strftime(3)` documentation. + .. versionadded:: 3.6 ``%G``, ``%u`` and ``%V`` were added. +Technical Detail +^^^^^^^^^^^^^^^^ + +Broadly speaking, ``d.strftime(fmt)`` acts like the :mod:`time` module's +``time.strftime(fmt, d.timetuple())`` although not all objects support a +:meth:`timetuple` method. + +For the :meth:`datetime.strptime` class method, the default value is +``1900-01-01T00:00:00.000``: any components not specified in the format string +will be pulled from the default value. [#]_ + +Using ``datetime.strptime(date_string, format)`` is equivalent to:: + + datetime(*(time.strptime(date_string, format)[0:6])) + +except when the format includes sub-second components or timezone offset +information, which are supported in ``datetime.strptime`` but are discarded by +``time.strptime``. + +For :class:`.time` objects, the format codes for year, month, and day should not +be used, as :class:`time` objects have no such values. If they're used anyway, +``1900`` is substituted for the year, and ``1`` for the month and day. + +For :class:`date` objects, the format codes for hours, minutes, seconds, and +microseconds should not be used, as :class:`date` objects have no such +values. If they're used anyway, ``0`` is substituted for them. + +For the same reason, handling of format strings containing Unicode code points +that can't be represented in the charset of the current locale is also +platform-dependent. On some platforms such code points are preserved intact in +the output, while on others ``strftime`` may raise :exc:`UnicodeError` or return +an empty string instead. + Notes: (1) @@ -2237,7 +2499,7 @@ Notes: (5) When used with the :meth:`strptime` method, the ``%f`` directive - accepts from one to six digits and zero pads on the right. ``%f`` is + accepts from one to six digits and zero pads on the right. ``%f`` is an extension to the set of format characters in the C standard (but implemented separately in datetime objects, and therefore always available). @@ -2250,13 +2512,13 @@ Notes: ``%z`` :meth:`utcoffset` is transformed into a string of the form - ±HHMM[SS[.ffffff]], where HH is a 2-digit string giving the number of UTC - offset hours, MM is a 2-digit string giving the number of UTC offset - minutes, SS is a 2-digit string giving the number of UTC offset - seconds and ffffff is a 6-digit string giving the number of UTC - offset microseconds. The ffffff part is omitted when the offset is a - whole number of seconds and both the ffffff and the SS part is omitted - when the offset is a whole number of minutes. For example, if + ``±HHMM[SS[.ffffff]]``, where ``HH`` is a 2-digit string giving the number + of UTC offset hours, ``MM`` is a 2-digit string giving the number of UTC + offset minutes, SS is a 2-digit string giving the number of UTC offset + seconds and ``ffffff`` is a 6-digit string giving the number of UTC + offset microseconds. The ``ffffff`` part is omitted when the offset is a + whole number of seconds and both the ``ffffff`` and the ``SS`` part is + omitted when the offset is a whole number of minutes. For example, if :meth:`utcoffset` returns ``timedelta(hours=-3, minutes=-30)``, ``%z`` is replaced with the string ``'-0330'``. @@ -2272,12 +2534,12 @@ Notes: ``%Z`` If :meth:`tzname` returns ``None``, ``%Z`` is replaced by an empty - string. Otherwise ``%Z`` is replaced by the returned value, which must + string. Otherwise ``%Z`` is replaced by the returned value, which must be a string. .. versionchanged:: 3.2 When the ``%z`` directive is provided to the :meth:`strptime` method, an - aware :class:`.datetime` object will be produced. The ``tzinfo`` of the + aware :class:`.datetime` object will be produced. The ``tzinfo`` of the result will be set to a :class:`timezone` instance. (7) @@ -2291,7 +2553,23 @@ Notes: :meth:`strptime` format string. Also note that ``%G`` and ``%Y`` are not interchangeable. +(9) + When used with the :meth:`strptime` method, the leading zero is optional + for formats ``%d``, ``%m``, ``%H``, ``%I``, ``%M``, ``%S``, ``%J``, ``%U``, + ``%W``, and ``%V``. Format ``%y`` does require a leading zero. + .. rubric:: Footnotes .. [#] If, that is, we ignore the effects of Relativity + +.. [#] This matches the definition of the "proleptic Gregorian" calendar in + Dershowitz and Reingold's book *Calendrical Calculations*, + where it's the base calendar for all computations. See the book for + algorithms for converting between proleptic Gregorian ordinals and + 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/debug.rst b/Doc/library/debug.rst index 88a2fa62a56588..60223657a44043 100644 --- a/Doc/library/debug.rst +++ b/Doc/library/debug.rst @@ -5,10 +5,13 @@ Debugging and Profiling These libraries help you with Python development: the debugger enables you to step through code, analyze stack frames and set breakpoints etc., and the profilers run code and give you a detailed breakdown of execution times, -allowing you to identify bottlenecks in your programs. +allowing you to identify bottlenecks in your programs. Auditing events +provide visibility into runtime behaviors that would otherwise require +intrusive debugging or patching. .. toctree:: + audit_events.rst bdb.rst faulthandler.rst pdb.rst diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index f044cb2d6e0a86..c2a19dc019bb37 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -127,6 +127,10 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. the next difference highlight at the top of the browser without any leading context). + .. note:: + *fromdesc* and *todesc* are interpreted as unescaped HTML and should be + properly escaped while receiving input from untrusted sources. + .. versionchanged:: 3.5 *charset* keyword-only argument was added. The default charset of HTML document changed from ``'ISO-8859-1'`` to ``'utf-8'``. @@ -543,6 +547,16 @@ The :class:`SequenceMatcher` class has this constructor: to try :meth:`quick_ratio` or :meth:`real_quick_ratio` first to get an upper bound. + .. note:: + + Caution: The result of a :meth:`ratio` call may depend on the order of + the arguments. For instance:: + + >>> SequenceMatcher(None, 'tide', 'diet').ratio() + 0.25 + >>> SequenceMatcher(None, 'diet', 'tide').ratio() + 0.5 + .. method:: quick_ratio() diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 2a3ffb5e827119..39a3e130afd3e0 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -645,10 +645,12 @@ the original TOS1. .. opcode:: MAP_ADD (i) - Calls ``dict.setitem(TOS1[-i], TOS, TOS1)``. Used to implement dict + Calls ``dict.__setitem__(TOS1[-i], TOS1, TOS)``. Used to implement dict comprehensions. .. versionadded:: 3.1 + .. versionchanged:: 3.8 + Map value is TOS and map key is TOS1. 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 @@ -1219,10 +1221,10 @@ All of the following opcodes use their arguments. .. opcode:: EXTENDED_ARG (ext) - Prefixes any opcode which has an argument too big to fit into the default two - bytes. *ext* holds two additional bytes which, taken together with the - subsequent opcode's argument, comprise a four-byte argument, *ext* being the - two most-significant bytes. + Prefixes any opcode which has an argument too big to fit into the default one + byte. *ext* holds an additional byte which act as higher bits in the argument. + For each opcode, at most three prefixal ``EXTENDED_ARG`` are allowed, forming + an argument from two-byte to four-byte. .. opcode:: FORMAT_VALUE (flags) diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index e7c0033eb6bc45..7fc471fe2ab7db 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -1,5 +1,3 @@ -:keepdoctest: - :mod:`doctest` --- Test interactive Python examples =================================================== diff --git a/Doc/library/ensurepip.rst b/Doc/library/ensurepip.rst index c797f63326d1a2..a2bb045e57e3c0 100644 --- a/Doc/library/ensurepip.rst +++ b/Doc/library/ensurepip.rst @@ -119,6 +119,8 @@ Module API *verbosity* controls the level of output to :data:`sys.stdout` from the bootstrapping operation. + .. audit-event:: ensurepip.bootstrap root ensurepip.bootstrap + .. note:: The bootstrapping process has side effects on both ``sys.path`` and diff --git a/Doc/library/faulthandler.rst b/Doc/library/faulthandler.rst index 94ebd87639c501..b588dfa18db2dd 100644 --- a/Doc/library/faulthandler.rst +++ b/Doc/library/faulthandler.rst @@ -100,8 +100,10 @@ Dumping the tracebacks after a timeout :func:`cancel_dump_traceback_later` is called: see :ref:`issue with file descriptors `. - This function is implemented using a watchdog thread and therefore is not - available if Python is compiled with threads disabled. + This function is implemented using a watchdog thread. + + .. versionchanged:: 3.7 + This function is now always available. .. versionchanged:: 3.5 Added support for passing file descriptor to this function. diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 2db9674952d7b6..a7390150f7910d 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -120,7 +120,8 @@ The module defines the following functions: .. function:: lockf(fd, cmd, len=0, start=0, whence=0) This is essentially a wrapper around the :func:`~fcntl.fcntl` locking calls. - *fd* is the file descriptor of the file to lock or unlock, and *cmd* + *fd* is the file descriptor (file objects providing a :meth:`~io.IOBase.fileno` + method are accepted as well) of the file to lock or unlock, and *cmd* is one of the following values: * :const:`LOCK_UN` -- unlock @@ -171,4 +172,3 @@ using the :func:`flock` call may be better. present in the :mod:`os` module (on BSD only), the :func:`os.open` function provides an alternative to the :func:`lockf` and :func:`flock` functions. - diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index b5a818e1cafa61..58e7126b0bf212 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -94,6 +94,13 @@ another rational number, or from a string. Denominator of the Fraction in lowest term. + .. method:: as_integer_ratio() + + Return a tuple of two integers, whose ratio is equal + to the Fraction and with a positive denominator. + + .. versionadded:: 3.8 + .. method:: from_float(flt) This class method constructs a :class:`Fraction` representing the exact diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst index 6c39f9a59fc1fd..db0212367340d9 100644 --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -33,7 +33,8 @@ Here's a sample session using the :mod:`ftplib` module:: drwxr-sr-x 4 1176 1176 4096 Nov 17 2008 project drwxr-xr-x 3 1176 1176 4096 Oct 10 2012 tools '226 Directory send OK.' - >>> ftp.retrbinary('RETR README', open('README', 'wb').write) + >>> with open('README', 'wb') as fp: + >>> ftp.retrbinary('RETR README', fp.write) '226 Transfer complete.' >>> ftp.quit() @@ -144,7 +145,7 @@ The module defines the following items: The set of all exceptions (as a tuple) that methods of :class:`FTP` instances may raise as a result of problems with the FTP connection (as opposed to programming errors made by the caller). This set includes the - four exceptions listed above as well as :exc:`OSError`. + four exceptions listed above as well as :exc:`OSError` and :exc:`EOFError`. .. seealso:: @@ -190,6 +191,8 @@ followed by ``lines`` for the text version or ``binary`` for the binary version. *source_address* is a 2-tuple ``(host, port)`` for the socket to bind to as its source address before connecting. + .. audit-event:: ftplib.connect self,host,port ftplib.FTP.connect + .. versionchanged:: 3.3 *source_address* parameter was added. @@ -223,6 +226,8 @@ followed by ``lines`` for the text version or ``binary`` for the binary version. Send a simple command string to the server and return the response string. + .. audit-event:: ftplib.sendcmd self,cmd ftplib.FTP.sendcmd + .. method:: FTP.voidcmd(cmd) @@ -230,6 +235,8 @@ followed by ``lines`` for the text version or ``binary`` for the binary version. nothing if a response code corresponding to success (codes in the range 200--299) is received. Raise :exc:`error_reply` otherwise. + .. audit-event:: ftplib.sendcmd self,cmd ftplib.FTP.voidcmd + .. method:: FTP.retrbinary(cmd, callback, blocksize=8192, rest=None) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 415a65b4946f08..0236ff03da0741 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -128,6 +128,8 @@ are always available. They are listed here in alphabetical order. :func:`breakpoint` will automatically call that, allowing you to drop into the debugger of choice. + .. audit-event:: builtins.breakpoint breakpointhook breakpoint + .. versionadded:: 3.7 .. _func-bytearray: @@ -275,9 +277,9 @@ are always available. They are listed here in alphabetical order. If you want to parse Python code into its AST representation, see :func:`ast.parse`. - .. audit-event:: compile "source filename" + .. audit-event:: compile source,filename compile - Raises an :func:`auditing event ` ``compile`` with arguments + Raises an :ref:`auditing event ` ``compile`` with arguments ``source`` and ``filename``. This event may also be raised by implicit compilation. @@ -452,7 +454,7 @@ are always available. They are listed here in alphabetical order. n += 1 -.. function:: eval(expression, globals=None, locals=None) +.. function:: eval(expression[, globals[, locals]]) The arguments are a string and optional globals and locals. If provided, *globals* must be a dictionary. If provided, *locals* can be any mapping @@ -463,12 +465,16 @@ are always available. They are listed here in alphabetical order. dictionaries as global and local namespace. If the *globals* dictionary is present and does not contain a value for the key ``__builtins__``, a reference to the dictionary of the built-in module :mod:`builtins` is - inserted under that key before *expression* is parsed. - This means that *expression* normally has full - access to the standard :mod:`builtins` module and restricted environments are - propagated. If the *locals* dictionary is omitted it defaults to the *globals* - dictionary. If both dictionaries are omitted, the expression is executed in the - environment where :func:`eval` is called. The return value is the result of + inserted under that key before *expression* is parsed. This means that + *expression* normally has full access to the standard :mod:`builtins` + module and restricted environments are propagated. If the *locals* + dictionary is omitted it defaults to the *globals* dictionary. If both + dictionaries are omitted, the expression is executed with the *globals* and + *locals* in the environment where :func:`eval` is called. Note, *eval()* + does not have access to the :term:`nested scope`\s (non-locals) in the + enclosing environment. + + The return value is the result of the evaluated expression. Syntax errors are reported as exceptions. Example: >>> x = 1 @@ -488,10 +494,10 @@ are always available. They are listed here in alphabetical order. See :func:`ast.literal_eval` for a function that can safely evaluate strings with expressions containing only literals. - .. audit-event:: exec code_object + .. audit-event:: exec code_object eval - Raises an :func:`auditing event ` ``exec`` with the code object as - the argument. Code compilation events may also be raised. + Raises an :ref:`auditing event ` ``exec`` with the code object + as the argument. Code compilation events may also be raised. .. index:: builtin: exec @@ -523,10 +529,10 @@ 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`. - .. audit-event:: exec code_object + .. audit-event:: exec code_object exec - Raises an :func:`auditing event ` ``exec`` with the code object as - the argument. Code compilation events may also be raised. + Raises an :ref:`auditing event ` ``exec`` with the code object + as the argument. Code compilation events may also be raised. .. note:: @@ -777,12 +783,12 @@ are always available. They are listed here in alphabetical order. If the :mod:`readline` module was loaded, then :func:`input` will use it to provide elaborate line editing and history features. - .. audit-event:: builtins.input prompt + .. audit-event:: builtins.input prompt input - Raises an :func:`auditing event ` ``builtins.input`` with + Raises an :ref:`auditing event ` ``builtins.input`` with argument ``prompt`` before reading input - .. audit-event:: builtins.input/result result + .. audit-event:: builtins.input/result result input Raises an auditing event ``builtins.input/result`` with the result after successfully reading input. @@ -1062,12 +1068,12 @@ are always available. They are listed here in alphabetical order. ``'a'`` open for writing, appending to the end of the file if it exists ``'b'`` binary mode ``'t'`` text mode (default) - ``'+'`` open a disk file for updating (reading and writing) + ``'+'`` open for updating (reading and writing) ========= =============================================================== The default mode is ``'r'`` (open for reading text, synonym of ``'rt'``). - For binary read-write access, the mode ``'w+b'`` opens and truncates the file - to 0 bytes. ``'r+b'`` opens the file without truncation. + Modes ``'w+'`` and ``'w+b'`` open and truncate the file. Modes ``'r+'`` + and ``'r+b'`` open the file with no truncation. As mentioned in the :ref:`io-overview`, Python distinguishes between binary and text I/O. Files opened in binary mode (including ``'b'`` in the *mode* @@ -1220,7 +1226,7 @@ are always available. They are listed here in alphabetical order. (where :func:`open` is declared), :mod:`os`, :mod:`os.path`, :mod:`tempfile`, and :mod:`shutil`. - .. audit-event:: open "file mode flags" + .. audit-event:: open file,mode,flags open The ``mode`` and ``flags`` arguments may have been modified or inferred from the original call. @@ -1266,11 +1272,12 @@ are always available. They are listed here in alphabetical order. returns ``8364``. This is the inverse of :func:`chr`. -.. function:: pow(x, y[, z]) +.. function:: pow(base, exp[, mod]) - Return *x* to the power *y*; if *z* is present, return *x* to the power *y*, - modulo *z* (computed more efficiently than ``pow(x, y) % z``). The two-argument - form ``pow(x, y)`` is equivalent to using the power operator: ``x**y``. + Return *base* to the power *exp*; if *mod* is present, return *base* to the + power *exp*, modulo *mod* (computed more efficiently than + ``pow(base, exp) % mod``). The two-argument form ``pow(base, exp)`` is + equivalent to using the power operator: ``base**exp``. The arguments must have numeric types. With mixed operand types, the coercion rules for binary arithmetic operators apply. For :class:`int` @@ -1279,14 +1286,15 @@ are always available. They are listed here in alphabetical order. converted to float and a float result is delivered. For example, ``10**2`` returns ``100``, but ``10**-2`` returns ``0.01``. - For :class:`int` operands *x* and *y*, if *z* is present, *z* must also be - of integer type and *z* must be nonzero. If *z* is present and *y* is - negative, *x* must be relatively prime to *z*. In that case, ``pow(inv_x, - -y, z)`` is returned, where *inv_x* is an inverse to *x* modulo *z*. + For :class:`int` operands *base* and *exp*, if *mod* is present, *mod* must + also be of integer type and *mod* must be nonzero. If *mod* is present and + *exp* is negative, *base* must be relatively prime to *mod*. In that case, + ``pow(inv_base, -exp, mod)`` is returned, where *inv_base* is an inverse to + *base* modulo *mod*. Here's an example of computing an inverse for ``38`` modulo ``97``:: - >>> pow(38, -1, 97) + >>> pow(38, -1, mod=97) 23 >>> 23 * 38 % 97 == 1 True @@ -1296,6 +1304,10 @@ are always available. They are listed here in alphabetical order. the second argument to be negative, permitting computation of modular inverses. + .. versionchanged:: 3.9 + Allow keyword arguments. Formerly, only positional arguments were + supported. + .. function:: print(*objects, sep=' ', end='\\n', file=sys.stdout, flush=False) @@ -1562,11 +1574,11 @@ are always available. They are listed here in alphabetical order. about strings, see :ref:`textseq`. -.. function:: sum(iterable[, start]) +.. function:: sum(iterable, /, start=0) Sums *start* and the items of an *iterable* from left to right and returns the - total. *start* defaults to ``0``. The *iterable*'s items are normally numbers, - and the start value is not allowed to be a string. + total. The *iterable*'s items are normally numbers, and the start value is not + allowed to be a string. For some use cases, there are good alternatives to :func:`sum`. The preferred, fast way to concatenate a sequence of strings is by calling @@ -1581,10 +1593,17 @@ are always available. They are listed here in alphabetical order. 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 search order is same as that used by - :func:`getattr` except that the *type* itself is skipped. + been overridden in a class. + + The *object-or-type* determines the :term:`method resolution order` + to be searched. The search starts from the class right after the + *type*. - The :attr:`~class.__mro__` attribute of the *type* lists the method + 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 resolution search order used by both :func:`getattr` and :func:`super`. The attribute is dynamic and can change whenever the inheritance hierarchy is updated. @@ -1616,6 +1635,10 @@ are always available. They are listed here in alphabetical order. super().method(arg) # This does the same thing as: # super(C, self).method(arg) + In addition to method lookups, :func:`super` also works for attribute + lookups. One possible use case for this is calling :term:`descriptor`\s + in a parent or sibling class. + Note that :func:`super` is implemented as part of the binding process for explicit dotted attribute lookups such as ``super().__getitem__(name)``. It does so by implementing its own :meth:`__getattribute__` method for searching diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst index 2a5f0ddc4ef319..92a8c4d1eb871c 100644 --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -49,8 +49,11 @@ For example, ``'[?]'`` matches the character ``'?'``. single: **; in glob-style wildcards If *recursive* is true, the pattern "``**``" will match any files and zero or - more directories and subdirectories. If the pattern is followed by an - ``os.sep``, only directories and subdirectories match. + more directories, subdirectories and symbolic links to directories. If the + pattern is followed by an :data:`os.sep` or :data:`os.altsep` then files will not + match. + + .. audit-event:: glob.glob pathname,recursive glob.glob .. note:: Using the "``**``" pattern in large directory trees may consume @@ -65,6 +68,8 @@ For example, ``'[?]'`` matches the character ``'?'``. Return an :term:`iterator` which yields the same values as :func:`glob` without actually storing them all simultaneously. + .. audit-event:: glob.glob pathname,recursive glob.iglob + .. function:: escape(pathname) diff --git a/Doc/library/hmac.rst b/Doc/library/hmac.rst index dc994b07c35c00..57ac8bb16120f5 100644 --- a/Doc/library/hmac.rst +++ b/Doc/library/hmac.rst @@ -14,12 +14,13 @@ This module implements the HMAC algorithm as described by :rfc:`2104`. -.. function:: new(key, msg=None, digestmod=None) +.. function:: new(key, msg=None, digestmod='') Return a new hmac object. *key* is a bytes or bytearray object giving the secret key. If *msg* is present, the method call ``update(msg)`` is made. *digestmod* is the digest name, digest constructor or module for the HMAC - object to use. It supports any name suitable to :func:`hashlib.new`. + object to use. It may be any name suitable to :func:`hashlib.new`. + Despite its argument position, it is required. .. versionchanged:: 3.4 Parameter *key* can be a bytes or bytearray object. @@ -28,6 +29,8 @@ This module implements the HMAC algorithm as described by :rfc:`2104`. .. deprecated-removed:: 3.4 3.8 MD5 as implicit default digest for *digestmod* is deprecated. + The digestmod parameter is now required. Pass it as a keyword + argument to avoid awkwardness when you do not have an initial msg. .. function:: digest(key, msg, digest) @@ -127,7 +130,6 @@ This module also provides the following helper function: a timing attack could theoretically reveal information about the types and lengths of *a* and *b*—but not their values. - .. versionadded:: 3.3 diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index beaa720d732b4c..db26d56af30fb4 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -94,6 +94,11 @@ The module provides the following classes: :func:`ssl._create_unverified_context` can be passed to the *context* parameter. + .. versionchanged:: 3.8 + This class now enables TLS 1.3 + :attr:`ssl.SSLContext.post_handshake_auth` for the default *context* or + when *cert_file* is passed with a custom *context*. + .. deprecated:: 3.6 *key_file* and *cert_file* are deprecated in favor of *context*. @@ -511,8 +516,8 @@ Here is an example session that uses the ``GET`` method:: >>> # The following example demonstrates reading data in chunks. >>> conn.request("GET", "/") >>> r1 = conn.getresponse() - >>> while not r1.closed: - ... print(r1.read(200)) # 200 bytes + >>> while chunk := r1.read(200): + ... print(repr(chunk)) b'\n POP_JUMP_IF_TRUE' def unot(x): @@ -26,6 +62,7 @@ def unot(x): self.assertNotInBytecode(unot, 'UNARY_NOT') self.assertNotInBytecode(unot, 'POP_JUMP_IF_FALSE') self.assertInBytecode(unot, 'POP_JUMP_IF_TRUE') + self.check_lnotab(unot) def test_elim_inversion_of_is_or_in(self): for line, cmp_op in ( @@ -36,6 +73,7 @@ def test_elim_inversion_of_is_or_in(self): ): code = compile(line, '', 'single') self.assertInBytecode(code, 'COMPARE_OP', cmp_op) + self.check_lnotab(code) def test_global_as_constant(self): # LOAD_GLOBAL None/True/False --> LOAD_CONST None/True/False @@ -53,6 +91,7 @@ def h(): for func, elem in ((f, None), (g, True), (h, False)): self.assertNotInBytecode(func, 'LOAD_GLOBAL') self.assertInBytecode(func, 'LOAD_CONST', elem) + self.check_lnotab(func) def f(): 'Adding a docstring made this test fail in Py2.5.0' @@ -60,6 +99,7 @@ def f(): self.assertNotInBytecode(f, 'LOAD_GLOBAL') self.assertInBytecode(f, 'LOAD_CONST', None) + self.check_lnotab(f) def test_while_one(self): # Skip over: LOAD_CONST trueconst POP_JUMP_IF_FALSE xx @@ -71,6 +111,7 @@ def f(): self.assertNotInBytecode(f, elem) for elem in ('JUMP_ABSOLUTE',): self.assertInBytecode(f, elem) + self.check_lnotab(f) def test_pack_unpack(self): for line, elem in ( @@ -82,6 +123,7 @@ def test_pack_unpack(self): self.assertInBytecode(code, elem) self.assertNotInBytecode(code, 'BUILD_TUPLE') self.assertNotInBytecode(code, 'UNPACK_TUPLE') + self.check_lnotab(code) def test_folding_of_tuples_of_constants(self): for line, elem in ( @@ -94,6 +136,7 @@ def test_folding_of_tuples_of_constants(self): code = compile(line,'','single') self.assertInBytecode(code, 'LOAD_CONST', elem) self.assertNotInBytecode(code, 'BUILD_TUPLE') + self.check_lnotab(code) # Long tuples should be folded too. code = compile(repr(tuple(range(10000))),'','single') @@ -102,6 +145,7 @@ def test_folding_of_tuples_of_constants(self): load_consts = [instr for instr in dis.get_instructions(code) if instr.opname == 'LOAD_CONST'] self.assertEqual(len(load_consts), 2) + self.check_lnotab(code) # Bug 1053819: Tuple of constants misidentified when presented with: # . . . opcode_with_arg 100 unary_opcode BUILD_TUPLE 1 . . . @@ -119,6 +163,7 @@ def crater(): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ],) + self.check_lnotab(crater) def test_folding_of_lists_of_constants(self): for line, elem in ( @@ -131,6 +176,7 @@ def test_folding_of_lists_of_constants(self): code = compile(line, '', 'single') self.assertInBytecode(code, 'LOAD_CONST', elem) self.assertNotInBytecode(code, 'BUILD_LIST') + self.check_lnotab(code) def test_folding_of_sets_of_constants(self): for line, elem in ( @@ -144,6 +190,7 @@ def test_folding_of_sets_of_constants(self): code = compile(line, '', 'single') self.assertNotInBytecode(code, 'BUILD_SET') self.assertInBytecode(code, 'LOAD_CONST', elem) + self.check_lnotab(code) # Ensure that the resulting code actually works: def f(a): @@ -154,9 +201,11 @@ def g(a): self.assertTrue(f(3)) self.assertTrue(not f(4)) + self.check_lnotab(f) self.assertTrue(not g(3)) self.assertTrue(g(4)) + self.check_lnotab(g) def test_folding_of_binops_on_constants(self): @@ -181,41 +230,50 @@ def test_folding_of_binops_on_constants(self): self.assertInBytecode(code, 'LOAD_CONST', elem) for instr in dis.get_instructions(code): self.assertFalse(instr.opname.startswith('BINARY_')) + self.check_lnotab(code) # Verify that unfoldables are skipped code = compile('a=2+"b"', '', 'single') self.assertInBytecode(code, 'LOAD_CONST', 2) self.assertInBytecode(code, 'LOAD_CONST', 'b') + self.check_lnotab(code) # Verify that large sequences do not result from folding code = compile('a="x"*10000', '', 'single') self.assertInBytecode(code, 'LOAD_CONST', 10000) self.assertNotIn("x"*10000, code.co_consts) + self.check_lnotab(code) code = compile('a=1<<1000', '', 'single') self.assertInBytecode(code, 'LOAD_CONST', 1000) self.assertNotIn(1<<1000, code.co_consts) + self.check_lnotab(code) code = compile('a=2**1000', '', 'single') self.assertInBytecode(code, 'LOAD_CONST', 1000) self.assertNotIn(2**1000, code.co_consts) + self.check_lnotab(code) def test_binary_subscr_on_unicode(self): # valid code get optimized code = compile('"foo"[0]', '', 'single') self.assertInBytecode(code, 'LOAD_CONST', 'f') self.assertNotInBytecode(code, 'BINARY_SUBSCR') + self.check_lnotab(code) code = compile('"\u0061\uffff"[1]', '', 'single') self.assertInBytecode(code, 'LOAD_CONST', '\uffff') self.assertNotInBytecode(code,'BINARY_SUBSCR') + self.check_lnotab(code) # With PEP 393, non-BMP char get optimized code = compile('"\U00012345"[0]', '', 'single') self.assertInBytecode(code, 'LOAD_CONST', '\U00012345') self.assertNotInBytecode(code, 'BINARY_SUBSCR') + self.check_lnotab(code) # invalid code doesn't get optimized # out of range code = compile('"fuu"[10]', '', 'single') self.assertInBytecode(code, 'BINARY_SUBSCR') + self.check_lnotab(code) def test_folding_of_unaryops_on_constants(self): for line, elem in ( @@ -230,13 +288,15 @@ def test_folding_of_unaryops_on_constants(self): self.assertInBytecode(code, 'LOAD_CONST', elem) for instr in dis.get_instructions(code): self.assertFalse(instr.opname.startswith('UNARY_')) + self.check_lnotab(code) # Check that -0.0 works after marshaling def negzero(): return -(1.0-1.0) - for instr in dis.get_instructions(code): + for instr in dis.get_instructions(negzero): self.assertFalse(instr.opname.startswith('UNARY_')) + self.check_lnotab(negzero) # Verify that unfoldables are skipped for line, elem, opname in ( @@ -246,6 +306,7 @@ def negzero(): code = compile(line, '', 'single') self.assertInBytecode(code, 'LOAD_CONST', elem) self.assertInBytecode(code, opname) + self.check_lnotab(code) def test_elim_extra_return(self): # RETURN LOAD_CONST None RETURN --> RETURN @@ -255,16 +316,80 @@ def f(x): returns = [instr for instr in dis.get_instructions(f) if instr.opname == 'RETURN_VALUE'] self.assertEqual(len(returns), 1) + self.check_lnotab(f) def test_elim_jump_to_return(self): # JUMP_FORWARD to RETURN --> RETURN def f(cond, true_value, false_value): - return true_value if cond else false_value + # Intentionally use two-line expression to test issue37213. + return (true_value if cond + else false_value) + self.check_jump_targets(f) self.assertNotInBytecode(f, 'JUMP_FORWARD') self.assertNotInBytecode(f, 'JUMP_ABSOLUTE') returns = [instr for instr in dis.get_instructions(f) if instr.opname == 'RETURN_VALUE'] self.assertEqual(len(returns), 2) + self.check_lnotab(f) + + def test_elim_jump_to_uncond_jump(self): + # POP_JUMP_IF_FALSE to JUMP_FORWARD --> POP_JUMP_IF_FALSE to non-jump + def f(): + if a: + # Intentionally use two-line expression to test issue37213. + if (c + or d): + foo() + else: + baz() + self.check_jump_targets(f) + 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 + def f(): + while a: + # Intentionally use two-line expression to test issue37213. + if (c + or d): + a = foo() + self.check_jump_targets(f) + self.check_lnotab(f) + + def test_elim_jump_to_uncond_jump3(self): + # Intentionally use two-line expressions to test issue37213. + # JUMP_IF_FALSE_OR_POP to JUMP_IF_FALSE_OR_POP --> JUMP_IF_FALSE_OR_POP to non-jump + def f(a, b, c): + return ((a and b) + and c) + self.check_jump_targets(f) + self.check_lnotab(f) + self.assertEqual(count_instr_recursively(f, 'JUMP_IF_FALSE_OR_POP'), 2) + # JUMP_IF_TRUE_OR_POP to JUMP_IF_TRUE_OR_POP --> JUMP_IF_TRUE_OR_POP to non-jump + def f(a, b, c): + return ((a or b) + or c) + self.check_jump_targets(f) + self.check_lnotab(f) + self.assertEqual(count_instr_recursively(f, 'JUMP_IF_TRUE_OR_POP'), 2) + # JUMP_IF_FALSE_OR_POP to JUMP_IF_TRUE_OR_POP --> POP_JUMP_IF_FALSE to non-jump + def f(a, b, c): + return ((a and b) + or c) + self.check_jump_targets(f) + self.check_lnotab(f) + self.assertNotInBytecode(f, 'JUMP_IF_FALSE_OR_POP') + self.assertInBytecode(f, 'JUMP_IF_TRUE_OR_POP') + self.assertInBytecode(f, 'POP_JUMP_IF_FALSE') + # JUMP_IF_TRUE_OR_POP to JUMP_IF_FALSE_OR_POP --> POP_JUMP_IF_TRUE to non-jump + def f(a, b, c): + return ((a or b) + and c) + self.check_jump_targets(f) + self.check_lnotab(f) + self.assertNotInBytecode(f, 'JUMP_IF_TRUE_OR_POP') + self.assertInBytecode(f, 'JUMP_IF_FALSE_OR_POP') + self.assertInBytecode(f, 'POP_JUMP_IF_TRUE') def test_elim_jump_after_return1(self): # Eliminate dead code: jumps immediately after returns can't be reached @@ -282,6 +407,7 @@ def f(cond1, cond2): returns = [instr for instr in dis.get_instructions(f) if instr.opname == 'RETURN_VALUE'] self.assertLessEqual(len(returns), 6) + self.check_lnotab(f) def test_elim_jump_after_return2(self): # Eliminate dead code: jumps immediately after returns can't be reached @@ -296,6 +422,7 @@ def f(cond1, cond2): returns = [instr for instr in dis.get_instructions(f) if instr.opname == 'RETURN_VALUE'] self.assertLessEqual(len(returns), 2) + self.check_lnotab(f) def test_make_function_doesnt_bail(self): def f(): @@ -303,6 +430,7 @@ def g()->1+1: pass return g self.assertNotInBytecode(f, 'BINARY_ADD') + self.check_lnotab(f) def test_constant_folding(self): # Issue #11244: aggressive constant folding. @@ -323,17 +451,49 @@ def test_constant_folding(self): self.assertFalse(instr.opname.startswith('UNARY_')) self.assertFalse(instr.opname.startswith('BINARY_')) self.assertFalse(instr.opname.startswith('BUILD_')) + self.check_lnotab(code) def test_in_literal_list(self): def containtest(): return x in [a, b] self.assertEqual(count_instr_recursively(containtest, 'BUILD_LIST'), 0) + self.check_lnotab(containtest) def test_iterate_literal_list(self): def forloop(): for x in [a, b]: pass self.assertEqual(count_instr_recursively(forloop, 'BUILD_LIST'), 0) + self.check_lnotab(forloop) + + def test_condition_with_binop_with_bools(self): + def f(): + if True or False: + return 1 + return 0 + self.assertEqual(f(), 1) + self.check_lnotab(f) + + def test_if_with_if_expression(self): # XXX does this belong in 3.8? + # Check bpo-37289 + def f(x): + if (True if x else False): + return True + return False + self.assertTrue(f(True)) + self.check_lnotab(f) + + def test_trailing_nops(self): + # Check the lnotab of a function that even after trivial + # optimization has trailing nops, which the lnotab adjustment has to + # handle properly (bpo-38115). + def f(x): + while 1: + return 3 + while 1: + return 5 + return 6 + self.check_lnotab(f) class TestBuglets(unittest.TestCase): diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py index 5f7a879b935d92..2307b133dbd0d5 100644 --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -203,6 +203,13 @@ def get_dispatch_table(self): return collections.ChainMap({}, pickle.dispatch_table) +class PyPicklerHookTests(AbstractHookTests): + class CustomPyPicklerClass(pickle._Pickler, + AbstractCustomPicklerClass): + pass + pickler_class = CustomPyPicklerClass + + if has_c_implementation: class CPickleTests(AbstractPickleModuleTests): from _pickle import dump, dumps, load, loads, Pickler, Unpickler @@ -255,12 +262,6 @@ class CChainDispatchTableTests(AbstractDispatchTableTests): def get_dispatch_table(self): return collections.ChainMap({}, pickle.dispatch_table) - class PyPicklerHookTests(AbstractHookTests): - class CustomPyPicklerClass(pickle._Pickler, - AbstractCustomPicklerClass): - pass - pickler_class = CustomPyPicklerClass - class CPicklerHookTests(AbstractHookTests): class CustomCPicklerClass(_pickle.Pickler, AbstractCustomPicklerClass): pass diff --git a/Lib/test/test_picklebuffer.py b/Lib/test/test_picklebuffer.py index 7e72157fd02216..97981c882e825b 100644 --- a/Lib/test/test_picklebuffer.py +++ b/Lib/test/test_picklebuffer.py @@ -5,7 +5,6 @@ import gc from pickle import PickleBuffer -import sys import weakref import unittest diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 9cf17726d92e0d..3084663a8fadd5 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -2,13 +2,12 @@ import platform import subprocess import sys -import sysconfig -import tempfile import unittest from unittest import mock from test import support + class PlatformTest(unittest.TestCase): def clear_caches(self): platform._platform_cache.clear() @@ -20,37 +19,9 @@ def test_architecture(self): @support.skip_unless_symlink def test_architecture_via_symlink(self): # issue3762 - # On Windows, the EXE needs to know where pythonXY.dll and *.pyd is at - # so we add the directory to the path, PYTHONHOME and PYTHONPATH. - env = None - if sys.platform == "win32": - env = {k.upper(): os.environ[k] for k in os.environ} - env["PATH"] = "{};{}".format( - os.path.dirname(sys.executable), env.get("PATH", "")) - env["PYTHONHOME"] = os.path.dirname(sys.executable) - if sysconfig.is_python_build(True): - env["PYTHONPATH"] = os.path.dirname(os.__file__) - - def get(python, env=None): - cmd = [python, '-c', - 'import platform; print(platform.architecture())'] - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, env=env) - r = p.communicate() - if p.returncode: - print(repr(r[0])) - print(repr(r[1]), file=sys.stderr) - self.fail('unexpected return code: {0} (0x{0:08X})' - .format(p.returncode)) - return r - - real = os.path.realpath(sys.executable) - link = os.path.abspath(support.TESTFN) - os.symlink(real, link) - try: - self.assertEqual(get(real), get(link, env=env)) - finally: - os.remove(link) + with support.PythonSymlink() as py: + cmd = "-c", "import platform; print(platform.architecture())" + self.assertEqual(py.call_real(*cmd), py.call_link(*cmd)) def test_platform(self): for aliased in (False, True): @@ -275,6 +246,11 @@ def test_libc_ver(self): os.path.exists(sys.executable+'.exe'): # Cygwin horror executable = sys.executable + '.exe' + elif sys.platform == "win32" and not os.path.exists(sys.executable): + # App symlink appears to not exist, but we want the + # real executable here anyway + import _winapi + executable = _winapi.GetModuleFileName(0) else: executable = sys.executable platform.libc_ver(executable) diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index 20d4eeac12d4b2..7b1d854d1c0866 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -309,9 +309,11 @@ def test_noop(self): def test_rpop(self): self.assertOK(self.client.rpop('foo')) + @test_support.requires_hashdigest('md5') def test_apop_normal(self): self.assertOK(self.client.apop('foo', 'dummypassword')) + @test_support.requires_hashdigest('md5') def test_apop_REDOS(self): # Replace welcome with very long evil welcome. # NB The upper bound on welcome length is currently 2048. diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 5c93d0d507d252..9bdd2848afc81b 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -310,6 +310,8 @@ def test_preadv_flags(self): buf = [bytearray(i) for i in [5, 3, 2]] self.assertEqual(posix.preadv(fd, buf, 3, os.RWF_HIPRI), 10) self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf)) + except NotImplementedError: + self.skipTest("preadv2 not available") except OSError as inst: # Is possible that the macro RWF_HIPRI was defined at compilation time # but the option is not supported by the kernel or the runtime libc shared @@ -1366,6 +1368,7 @@ def test_sched_setaffinity(self): self.assertEqual(posix.sched_getaffinity(0), mask) self.assertRaises(OSError, posix.sched_setaffinity, 0, []) 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) @@ -1637,23 +1640,35 @@ def test_setsigmask_wrong_type(self): os.environ, setsigmask=[signal.NSIG, signal.NSIG+1]) - @unittest.skipIf(True, - "FIXME: bpo-35537: test fails is setsid is supported") - def test_start_new_session(self): - # For code coverage of calling setsid(). 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. - code = "import os; print(os.getpgid(os.getpid()))" + def test_setsid(self): + rfd, wfd = os.pipe() + self.addCleanup(os.close, rfd) try: - self.spawn_func(sys.executable, - [sys.executable, "-c", code], - os.environ, setsid=True) - except NotImplementedError as exc: - self.skipTest("setsid is not supported: %s" % exc) - else: - parent_pgid = os.getpgid(os.getpid()) - child_pgid = int(output) - self.assertNotEqual(parent_pgid, child_pgid) + os.set_inheritable(wfd, True) + + code = textwrap.dedent(f""" + import os + fd = {wfd} + sid = os.getsid(0) + os.write(fd, str(sid).encode()) + """) + + try: + pid = self.spawn_func(sys.executable, + [sys.executable, "-c", code], + os.environ, setsid=True) + except NotImplementedError as exc: + self.skipTest(f"setsid is not supported: {exc!r}") + except PermissionError as exc: + self.skipTest(f"setsid failed with: {exc!r}") + finally: + os.close(wfd) + + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + output = os.read(rfd, 100) + child_sid = int(output) + parent_sid = os.getsid(os.getpid()) + self.assertNotEqual(parent_sid, child_sid) @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index 983e2dd6ff2763..4d3d8976d60468 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -1,7 +1,6 @@ import os import posixpath import unittest -import warnings from posixpath import realpath, abspath, dirname, basename from test import support, test_genericpath from test.support import FakePath @@ -12,6 +11,7 @@ except ImportError: posix = None + # An absolute path to a temporary filename for testing. We can't rely on TESTFN # being an absolute path, so we need this. diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index 0b3934f6226e36..fafe17ce5f1b30 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -3,15 +3,13 @@ Nick Mathewson ''' -import os import sys from textwrap import dedent from types import FunctionType, MethodType, BuiltinFunctionType import pyclbr from unittest import TestCase, main as unittest_main -from test import support from test.test_importlib import util as test_importlib_util -from functools import partial + StaticMethodType = type(staticmethod(lambda: None)) ClassMethodType = type(classmethod(lambda c: None)) diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 6efdeb047c217d..c80477c50f0980 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -21,7 +21,6 @@ import xml.etree import xml.etree.ElementTree import textwrap -import threading from io import StringIO from collections import namedtuple from test.support.script_helper import assert_python_ok diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index 92fffc45f30a96..2b6c2d20e74612 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -285,7 +285,7 @@ def test_illegal(self): self.fail() except TypeError as e: self.assertEqual(str(e), - 'ParserCreate() argument 2 must be str or None, not int') + "ParserCreate() argument 'namespace_separator' must be str or None, not int") try: expat.ParserCreate(namespace_separator='too long') diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index c8528f97741dcc..46e2a8c540a72d 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1,7 +1,6 @@ # Some simple queue module tests, plus some failure conditions # to ensure the Queue locks remain stable. import itertools -import queue import random import threading import time @@ -9,11 +8,9 @@ import weakref from test import support - -try: - import _queue -except ImportError: - _queue = None +py_queue = support.import_fresh_module('queue', blocked=['_queue']) +c_queue = support.import_fresh_module('queue', fresh=['_queue']) +need_c_queue = unittest.skipUnless(c_queue, "No _queue module found") QUEUE_SIZE = 5 @@ -120,12 +117,12 @@ def basic_queue_test(self, q): try: q.put(full, block=0) self.fail("Didn't appear to block with a full queue") - except queue.Full: + except self.queue.Full: pass try: q.put(full, timeout=0.01) self.fail("Didn't appear to time-out with a full queue") - except queue.Full: + except self.queue.Full: pass # Test a blocking put self.do_blocking_test(q.put, (full,), q.get, ()) @@ -137,12 +134,12 @@ def basic_queue_test(self, q): try: q.get(block=0) self.fail("Didn't appear to block with an empty queue") - except queue.Empty: + except self.queue.Empty: pass try: q.get(timeout=0.01) self.fail("Didn't appear to time-out with an empty queue") - except queue.Empty: + except self.queue.Empty: pass # Test a blocking get self.do_blocking_test(q.get, (), q.put, ('empty',)) @@ -218,12 +215,12 @@ def test_nowait(self): q = self.type2test(QUEUE_SIZE) for i in range(QUEUE_SIZE): q.put_nowait(1) - with self.assertRaises(queue.Full): + with self.assertRaises(self.queue.Full): q.put_nowait(1) for i in range(QUEUE_SIZE): q.get_nowait() - with self.assertRaises(queue.Empty): + with self.assertRaises(self.queue.Empty): q.get_nowait() def test_shrinking_queue(self): @@ -232,45 +229,88 @@ def test_shrinking_queue(self): q.put(1) q.put(2) q.put(3) - with self.assertRaises(queue.Full): + with self.assertRaises(self.queue.Full): q.put_nowait(4) self.assertEqual(q.qsize(), 3) q.maxsize = 2 # shrink the queue - with self.assertRaises(queue.Full): + with self.assertRaises(self.queue.Full): q.put_nowait(4) -class QueueTest(BaseQueueTestMixin, unittest.TestCase): - type2test = queue.Queue +class QueueTest(BaseQueueTestMixin): + + def setUp(self): + self.type2test = self.queue.Queue + super().setUp() + +class PyQueueTest(QueueTest, unittest.TestCase): + queue = py_queue + + +@need_c_queue +class CQueueTest(QueueTest, unittest.TestCase): + queue = c_queue + + +class LifoQueueTest(BaseQueueTestMixin): + + def setUp(self): + self.type2test = self.queue.LifoQueue + super().setUp() + + +class PyLifoQueueTest(LifoQueueTest, unittest.TestCase): + queue = py_queue + + +@need_c_queue +class CLifoQueueTest(LifoQueueTest, unittest.TestCase): + queue = c_queue + + +class PriorityQueueTest(BaseQueueTestMixin): + + def setUp(self): + self.type2test = self.queue.PriorityQueue + super().setUp() + -class LifoQueueTest(BaseQueueTestMixin, unittest.TestCase): - type2test = queue.LifoQueue +class PyPriorityQueueTest(PriorityQueueTest, unittest.TestCase): + queue = py_queue -class PriorityQueueTest(BaseQueueTestMixin, unittest.TestCase): - type2test = queue.PriorityQueue +@need_c_queue +class CPriorityQueueTest(PriorityQueueTest, unittest.TestCase): + queue = c_queue # A Queue subclass that can provoke failure at a moment's notice :) -class FailingQueueException(Exception): - pass - -class FailingQueue(queue.Queue): - def __init__(self, *args): - self.fail_next_put = False - self.fail_next_get = False - queue.Queue.__init__(self, *args) - def _put(self, item): - if self.fail_next_put: - self.fail_next_put = False - raise FailingQueueException("You Lose") - return queue.Queue._put(self, item) - def _get(self): - if self.fail_next_get: - self.fail_next_get = False - raise FailingQueueException("You Lose") - return queue.Queue._get(self) - -class FailingQueueTest(BlockingTestMixin, unittest.TestCase): +class FailingQueueException(Exception): pass + +class FailingQueueTest(BlockingTestMixin): + + def setUp(self): + + Queue = self.queue.Queue + + class FailingQueue(Queue): + def __init__(self, *args): + self.fail_next_put = False + self.fail_next_get = False + Queue.__init__(self, *args) + def _put(self, item): + if self.fail_next_put: + self.fail_next_put = False + raise FailingQueueException("You Lose") + return Queue._put(self, item) + def _get(self): + if self.fail_next_get: + self.fail_next_get = False + raise FailingQueueException("You Lose") + return Queue._get(self) + + self.FailingQueue = FailingQueue + + super().setUp() def failing_queue_test(self, q): if q.qsize(): @@ -354,13 +394,24 @@ def failing_queue_test(self, q): self.assertTrue(not q.qsize(), "Queue should be empty") def test_failing_queue(self): + # Test to make sure a queue is functioning correctly. # Done twice to the same instance. - q = FailingQueue(QUEUE_SIZE) + q = self.FailingQueue(QUEUE_SIZE) self.failing_queue_test(q) self.failing_queue_test(q) + +class PyFailingQueueTest(FailingQueueTest, unittest.TestCase): + queue = py_queue + + +@need_c_queue +class CFailingQueueTest(FailingQueueTest, unittest.TestCase): + queue = c_queue + + class BaseSimpleQueueTest: def setUp(self): @@ -388,7 +439,7 @@ def consume_nonblock(self, q, results, sentinel): while True: try: val = q.get(block=False) - except queue.Empty: + except self.queue.Empty: time.sleep(1e-5) else: break @@ -401,7 +452,7 @@ def consume_timeout(self, q, results, sentinel): while True: try: val = q.get(timeout=1e-5) - except queue.Empty: + except self.queue.Empty: pass else: break @@ -470,11 +521,11 @@ def test_basic(self): self.assertTrue(q.empty()) self.assertEqual(q.qsize(), 0) - with self.assertRaises(queue.Empty): + with self.assertRaises(self.queue.Empty): q.get(block=False) - with self.assertRaises(queue.Empty): + with self.assertRaises(self.queue.Empty): q.get(timeout=1e-3) - with self.assertRaises(queue.Empty): + with self.assertRaises(self.queue.Empty): q.get_nowait() self.assertTrue(q.empty()) self.assertEqual(q.qsize(), 0) @@ -541,18 +592,25 @@ class C: class PySimpleQueueTest(BaseSimpleQueueTest, unittest.TestCase): - type2test = queue._PySimpleQueue + queue = py_queue + def setUp(self): + self.type2test = self.queue._PySimpleQueue + super().setUp() -@unittest.skipIf(_queue is None, "No _queue module found") + +@need_c_queue class CSimpleQueueTest(BaseSimpleQueueTest, unittest.TestCase): + queue = c_queue + def setUp(self): - self.type2test = _queue.SimpleQueue + self.type2test = self.queue.SimpleQueue super().setUp() def test_is_default(self): - self.assertIs(self.type2test, queue.SimpleQueue) + self.assertIs(self.type2test, self.queue.SimpleQueue) + self.assertIs(self.type2test, self.queue.SimpleQueue) def test_reentrancy(self): # bpo-14976: put() may be called reentrantly in an asynchronous diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index ff1ddcaf140745..899ca108c65d98 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -228,7 +228,7 @@ def test_choices(self): choices([], cum_weights=[], k=5) def test_choices_subnormal(self): - # Subnormal weights would occassionally trigger an IndexError + # Subnormal weights would occasionally trigger an IndexError # in choices() when the value returned by random() was large # enough to make `random() * total` round up to the total. # See https://bugs.python.org/msg275594 for more detail. diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 9155522c273d88..d2221b3448fa32 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -6,6 +6,7 @@ import contextlib import faulthandler +import glob import io import os.path import platform @@ -24,6 +25,7 @@ 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} )?' TEST_INTERRUPTED = textwrap.dedent(""" from signal import SIGINT, raise_signal @@ -389,8 +391,8 @@ def check_line(self, output, regex): self.assertRegex(output, regex) def parse_executed_tests(self, output): - regex = (r'^[0-9]+:[0-9]+:[0-9]+ (?:load avg: [0-9]+\.[0-9]{2} )?\[ *[0-9]+(?:/ *[0-9]+)*\] (%s)' - % self.TESTNAME_REGEX) + regex = (r'^%s\[ *[0-9]+(?:/ *[0-9]+)*\] (%s)' + % (LOG_PREFIX, self.TESTNAME_REGEX)) parser = re.finditer(regex, output, re.MULTILINE) return list(match.group(1) for match in parser) @@ -450,9 +452,10 @@ def list_regex(line_format, tests): if rerun: regex = list_regex('%s re-run test%s', rerun) self.check_line(output, regex) - self.check_line(output, "Re-running failed tests in verbose mode") + regex = LOG_PREFIX + r"Re-running failed tests in verbose mode" + self.check_line(output, regex) for test_name in rerun: - regex = f"Re-running {test_name} in verbose mode" + regex = LOG_PREFIX + f"Re-running {test_name} in verbose mode" self.check_line(output, regex) if no_test_ran: @@ -529,6 +532,31 @@ def run_python(self, args, **kw): return proc.stdout +class CheckActualTests(BaseTestCase): + """ + Check that regrtest appears to find the expected set of tests. + """ + + def test_finds_expected_number_of_tests(self): + args = ['-Wd', '-E', '-bb', '-m', 'test.regrtest', '--list-tests'] + output = self.run_python(args) + rough_number_of_tests_found = len(output.splitlines()) + actual_testsuite_glob = os.path.join(os.path.dirname(__file__), + 'test*.py') + rough_counted_test_py_files = len(glob.glob(actual_testsuite_glob)) + # We're not trying to duplicate test finding logic in here, + # just give a rough estimate of how many there should be and + # be near that. This is a regression test to prevent mishaps + # such as https://bugs.python.org/issue37667 in the future. + # If you need to change the values in here during some + # mythical future test suite reorganization, don't go + # overboard with logic and keep that goal in mind. + self.assertGreater(rough_number_of_tests_found, + rough_counted_test_py_files*9//10, + msg='Unexpectedly low number of tests found in:\n' + f'{", ".join(output.splitlines())}') + + class ProgramsTestCase(BaseTestCase): """ Test various ways to run the Python test suite. Use options close @@ -616,7 +644,9 @@ def test_tools_buildbot_test(self): # Tools\buildbot\test.bat script = os.path.join(ROOT_DIR, 'Tools', 'buildbot', 'test.bat') test_args = ['--testdir=%s' % self.tmptestdir] - if platform.architecture()[0] == '64bit': + if platform.machine() == 'ARM64': + test_args.append('-arm64') # ARM 64-bit build + elif platform.architecture()[0] == '64bit': test_args.append('-x64') # 64-bit build if not Py_DEBUG: test_args.append('+d') # Release build, use python.exe @@ -629,7 +659,9 @@ def test_pcbuild_rt(self): if not os.path.isfile(script): self.skipTest(f'File "{script}" does not exist') rt_args = ["-q"] # Quick, don't run tests twice - if platform.architecture()[0] == '64bit': + if platform.machine() == 'ARM64': + rt_args.append('-arm64') # ARM 64-bit build + elif platform.architecture()[0] == '64bit': rt_args.append('-x64') # 64-bit build if Py_DEBUG: rt_args.append('-d') # Debug build, use python_d.exe @@ -1120,6 +1152,48 @@ def test_garbage(self): env_changed=[testname], fail_env_changed=True) + def test_multiprocessing_timeout(self): + code = textwrap.dedent(r""" + import time + import unittest + try: + import faulthandler + except ImportError: + faulthandler = None + + class Tests(unittest.TestCase): + # test hangs and so should be stopped by the timeout + def test_sleep(self): + # we want to test regrtest multiprocessing timeout, + # not faulthandler timeout + if faulthandler is not None: + faulthandler.cancel_dump_traceback_later() + + time.sleep(60 * 5) + """) + testname = self.create_test(code=code) + + output = self.run_tests("-j2", "--timeout=1.0", testname, exitcode=2) + self.check_executed_tests(output, [testname], + failed=testname) + self.assertRegex(output, + re.compile('%s timed out' % testname, re.MULTILINE)) + + def test_cleanup(self): + dirname = os.path.join(self.tmptestdir, "test_python_123") + os.mkdir(dirname) + filename = os.path.join(self.tmptestdir, "test_python_456") + open(filename, "wb").close() + names = [dirname, filename] + + cmdargs = ['-m', 'test', + '--tempdir=%s' % self.tmptestdir, + '--cleanup'] + self.run_python(cmdargs) + + for name in names: + self.assertFalse(os.path.exists(name), name) + class TestUtils(unittest.TestCase): def test_format_duration(self): @@ -1130,9 +1204,9 @@ def test_format_duration(self): self.assertEqual(utils.format_duration(10e-3), '10 ms') self.assertEqual(utils.format_duration(1.5), - '1 sec 500 ms') + '1.5 sec') self.assertEqual(utils.format_duration(1), - '1 sec') + '1.0 sec') self.assertEqual(utils.format_duration(2 * 60), '2 min') self.assertEqual(utils.format_duration(2 * 60 + 1), diff --git a/Lib/test/test_robotparser.py b/Lib/test/test_robotparser.py index 84a267ad9567ee..77cd7c4d29dfe6 100644 --- a/Lib/test/test_robotparser.py +++ b/Lib/test/test_robotparser.py @@ -97,30 +97,38 @@ class RejectAllRobotsTest(BaseRobotTest, unittest.TestCase): class BaseRequestRateTest(BaseRobotTest): + request_rate = None + crawl_delay = None def test_request_rate(self): + parser = self.parser for url in self.good + self.bad: agent, url = self.get_agent_and_url(url) with self.subTest(url=url, agent=agent): - if self.crawl_delay: - self.assertEqual( - self.parser.crawl_delay(agent), self.crawl_delay - ) - if self.request_rate: + self.assertEqual(parser.crawl_delay(agent), self.crawl_delay) + + parsed_request_rate = parser.request_rate(agent) + self.assertEqual(parsed_request_rate, self.request_rate) + if self.request_rate is not None: self.assertIsInstance( - self.parser.request_rate(agent), + parsed_request_rate, urllib.robotparser.RequestRate ) self.assertEqual( - self.parser.request_rate(agent).requests, + parsed_request_rate.requests, self.request_rate.requests ) self.assertEqual( - self.parser.request_rate(agent).seconds, + parsed_request_rate.seconds, self.request_rate.seconds ) +class EmptyFileTest(BaseRequestRateTest, unittest.TestCase): + robots_txt = '' + good = ['/foo'] + + class CrawlDelayAndRequestRateTest(BaseRequestRateTest, unittest.TestCase): robots_txt = """\ User-agent: figtree @@ -141,10 +149,6 @@ class CrawlDelayAndRequestRateTest(BaseRequestRateTest, unittest.TestCase): class DifferentAgentTest(CrawlDelayAndRequestRateTest): agent = 'FigTree Robot libwww-perl/5.04' - # these are not actually tested, but we still need to parse it - # in order to accommodate the input parameters - request_rate = None - crawl_delay = None class InvalidRequestRateTest(BaseRobotTest, unittest.TestCase): diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 800b483b7e1501..f0030861116397 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -11,8 +11,7 @@ from test.support import ( forget, make_legacy_pyc, unload, verbose, no_tracing, create_empty_file, temp_dir) -from test.support.script_helper import ( - make_pkg, make_script, make_zip_pkg, make_zip_script) +from test.support.script_helper import make_script, make_zip_script import runpy diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index bb1081f034fe80..e4766ab190be01 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -895,6 +895,12 @@ def test_pickling(self): self.assertEqual(self.set, copy, "%s != %s" % (self.set, copy)) + def test_issue_37219(self): + with self.assertRaises(TypeError): + set().difference(123) + with self.assertRaises(TypeError): + set().difference_update(123) + #------------------------------------------------------------------------------ class TestBasicOpsEmpty(TestBasicOps, unittest.TestCase): diff --git a/Lib/test/test_shlex.py b/Lib/test/test_shlex.py index 376c5e88d3819d..a21ccd2fdf44a7 100644 --- a/Lib/test/test_shlex.py +++ b/Lib/test/test_shlex.py @@ -353,6 +353,13 @@ def testJoinRoundtrip(self): resplit = shlex.split(joined) self.assertEqual(split_command, resplit) + def testPunctuationCharsReadOnly(self): + punctuation_chars = "/|$%^" + shlex_instance = shlex.shlex(punctuation_chars=punctuation_chars) + self.assertEqual(shlex_instance.punctuation_chars, punctuation_chars) + with self.assertRaises(AttributeError): + shlex_instance.punctuation_chars = False + # Allow this test to be used with old shlex.py if not getattr(shlex, "split", None): diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 208718bb128105..636e3bd9795593 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -42,6 +42,11 @@ except ImportError: UID_GID_SUPPORT = False +try: + import _winapi +except ImportError: + _winapi = None + def _fake_rename(*args, **kwargs): # Pretend the destination path is on a different filesystem. raise OSError(getattr(errno, 'EXDEV', 18), "Invalid cross-device link") @@ -124,7 +129,7 @@ def supports_file2file_sendfile(): with open(srcname, "rb") as src: with tempfile.NamedTemporaryFile("wb", delete=False) as dst: - dstname = f.name + dstname = dst.name infd = src.fileno() outfd = dst.fileno() try: @@ -226,6 +231,47 @@ def test_rmtree_works_on_symlinks(self): self.assertTrue(os.path.exists(dir3)) self.assertTrue(os.path.exists(file1)) + @unittest.skipUnless(_winapi, 'only relevant on Windows') + def test_rmtree_fails_on_junctions(self): + tmp = self.mkdtemp() + dir_ = os.path.join(tmp, 'dir') + os.mkdir(dir_) + link = os.path.join(tmp, 'link') + _winapi.CreateJunction(dir_, link) + self.assertRaises(OSError, shutil.rmtree, link) + self.assertTrue(os.path.exists(dir_)) + self.assertTrue(os.path.lexists(link)) + errors = [] + def onerror(*args): + errors.append(args) + shutil.rmtree(link, onerror=onerror) + self.assertEqual(len(errors), 1) + self.assertIs(errors[0][0], os.path.islink) + self.assertEqual(errors[0][1], link) + self.assertIsInstance(errors[0][2][1], OSError) + + @unittest.skipUnless(_winapi, 'only relevant on Windows') + def test_rmtree_works_on_junctions(self): + tmp = self.mkdtemp() + dir1 = os.path.join(tmp, 'dir1') + dir2 = os.path.join(dir1, 'dir2') + dir3 = os.path.join(tmp, 'dir3') + for d in dir1, dir2, dir3: + os.mkdir(d) + file1 = os.path.join(tmp, 'file1') + write_file(file1, 'foo') + link1 = os.path.join(dir1, 'link1') + _winapi.CreateJunction(dir2, link1) + link2 = os.path.join(dir1, 'link2') + _winapi.CreateJunction(dir3, link2) + link3 = os.path.join(dir1, 'link3') + _winapi.CreateJunction(file1, link3) + # make sure junctions are removed but not followed + shutil.rmtree(dir1) + self.assertFalse(os.path.exists(dir1)) + self.assertTrue(os.path.exists(dir3)) + self.assertTrue(os.path.exists(file1)) + def test_rmtree_errors(self): # filename is guaranteed not to exist filename = tempfile.mktemp() @@ -754,8 +800,12 @@ def test_copytree_symlinks(self): src_stat = os.lstat(src_link) shutil.copytree(src_dir, dst_dir, symlinks=True) self.assertTrue(os.path.islink(os.path.join(dst_dir, 'sub', 'link'))) - self.assertEqual(os.readlink(os.path.join(dst_dir, 'sub', 'link')), - os.path.join(src_dir, 'file.txt')) + actual = os.readlink(os.path.join(dst_dir, 'sub', 'link')) + # Bad practice to blindly strip the prefix as it may be required to + # correctly refer to the file, but we're only comparing paths here. + if os.name == 'nt' and actual.startswith('\\\\?\\'): + actual = actual[4:] + self.assertEqual(actual, os.path.join(src_dir, 'file.txt')) dst_stat = os.lstat(dst_link) if hasattr(os, 'lchmod'): self.assertEqual(dst_stat.st_mode, src_stat.st_mode) @@ -878,14 +928,14 @@ def custom_cpfun(a, b): flag = [] src = tempfile.mkdtemp() + self.addCleanup(support.rmtree, src) dst = tempfile.mktemp() - self.addCleanup(shutil.rmtree, src) + self.addCleanup(support.rmtree, dst) with open(os.path.join(src, 'foo'), 'w') as f: f.close() shutil.copytree(src, dst, copy_function=custom_cpfun) self.assertEqual(len(flag), 1) - @unittest.skipIf(os.name == 'nt', 'temporarily disabled on Windows') @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') def test_dont_copy_file_onto_link_to_itself(self): # bug 851123. @@ -940,6 +990,20 @@ def test_rmtree_on_symlink(self): finally: shutil.rmtree(TESTFN, ignore_errors=True) + @unittest.skipUnless(_winapi, 'only relevant on Windows') + def test_rmtree_on_junction(self): + os.mkdir(TESTFN) + try: + src = os.path.join(TESTFN, 'cheese') + dst = os.path.join(TESTFN, 'shop') + os.mkdir(src) + open(os.path.join(src, 'spam'), 'wb').close() + _winapi.CreateJunction(src, dst) + self.assertRaises(OSError, shutil.rmtree, dst) + shutil.rmtree(dst, ignore_errors=True) + finally: + shutil.rmtree(TESTFN, ignore_errors=True) + # Issue #3002: copyfile and copytree block indefinitely on named pipes @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()') def test_copyfile_named_pipe(self): @@ -1870,11 +1934,7 @@ def test_move_dangling_symlink(self): dst_link = os.path.join(self.dst_dir, 'quux') shutil.move(dst, dst_link) self.assertTrue(os.path.islink(dst_link)) - # On Windows, os.path.realpath does not follow symlinks (issue #9949) - if os.name == 'nt': - self.assertEqual(os.path.realpath(src), os.readlink(dst_link)) - else: - self.assertEqual(os.path.realpath(src), os.path.realpath(dst_link)) + self.assertEqual(os.path.realpath(src), os.path.realpath(dst_link)) @support.skip_unless_symlink @mock_rename diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 063b35ca230f59..d41e94b07f4309 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -6,7 +6,6 @@ import statistics import subprocess import sys -import threading import time import unittest from test import support diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index fdcf6f21925645..d0c9862edea93f 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -4,6 +4,7 @@ from email.message import EmailMessage from email.base64mime import body_encode as encode_base64 import email.utils +import hashlib import hmac import socket import smtpd @@ -19,8 +20,9 @@ import unittest from test import support, mock_socket -from test.support import HOST, HOSTv4, HOSTv6 +from test.support import HOST from test.support import threading_setup, threading_cleanup, join_thread +from test.support import requires_hashdigest from unittest.mock import Mock @@ -1009,6 +1011,7 @@ def testAUTH_LOGIN(self): self.assertEqual(resp, (235, b'Authentication Succeeded')) smtp.close() + @requires_hashdigest('md5') def testAUTH_CRAM_MD5(self): self.serv.add_feature("AUTH CRAM-MD5") smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) @@ -1025,7 +1028,13 @@ def testAUTH_multiple(self): smtp.close() def test_auth_function(self): - supported = {'CRAM-MD5', 'PLAIN', 'LOGIN'} + supported = {'PLAIN', 'LOGIN'} + try: + hashlib.md5() + except ValueError: + pass + else: + supported.add('CRAM-MD5') for mechanism in supported: self.serv.add_feature("AUTH {}".format(mechanism)) for mechanism in supported: diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 74662cfeb327af..1bf562a03d556c 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1872,6 +1872,19 @@ def testBCMConstants(self): socket.CAN_BCM_RX_TIMEOUT # cyclic message is absent socket.CAN_BCM_RX_CHANGED # updated CAN frame (detected content change) + # flags + socket.CAN_BCM_SETTIMER + socket.CAN_BCM_STARTTIMER + socket.CAN_BCM_TX_COUNTEVT + socket.CAN_BCM_TX_ANNOUNCE + socket.CAN_BCM_TX_CP_CAN_ID + socket.CAN_BCM_RX_FILTER_ID + socket.CAN_BCM_RX_CHECK_DLC + socket.CAN_BCM_RX_NO_AUTOTIMER + socket.CAN_BCM_RX_ANNOUNCE_RESUME + socket.CAN_BCM_TX_RESET_MULTI_IDX + socket.CAN_BCM_RX_RTR_FRAME + def testCreateSocket(self): with socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) as s: pass @@ -1884,7 +1897,9 @@ def testCreateBCMSocket(self): def testBindAny(self): with socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) as s: - s.bind(('', )) + address = ('', ) + s.bind(address) + self.assertEqual(s.getsockname(), address) def testTooLongInterfaceName(self): # most systems limit IFNAMSIZ to 16, take 1024 to be sure @@ -4814,8 +4829,15 @@ def test_create_connection_timeout(self): # Issue #9792: create_connection() should not recast timeout errors # as generic socket errors. with self.mocked_socket_module(): - with self.assertRaises(socket.timeout): + try: socket.create_connection((HOST, 1234)) + except socket.timeout: + pass + except OSError as exc: + if support.IPV6_ENABLED or exc.errno != errno.EAFNOSUPPORT: + raise + else: + self.fail('socket.timeout not raised') class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest): diff --git a/Lib/test/test_source_encoding.py b/Lib/test/test_source_encoding.py index 38734009c00852..a0bd741c36ac29 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -31,7 +31,7 @@ def test_issue2301(self): try: compile(b"# coding: cp932\nprint '\x94\x4e'", "dummy", "exec") except SyntaxError as v: - self.assertEqual(v.text, "print '\u5e74'\n") + self.assertEqual(v.text.rstrip('\n'), "print '\u5e74'") else: self.fail() diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 7ba8156eef5da8..419506f4d3c072 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -19,6 +19,7 @@ import weakref import platform import sysconfig +import functools try: import ctypes except ImportError: @@ -26,7 +27,7 @@ ssl = support.import_module("ssl") -from ssl import TLSVersion, _TLSContentType, _TLSMessageType, _TLSAlertType +from ssl import TLSVersion, _TLSContentType, _TLSMessageType PROTOCOLS = sorted(ssl._PROTOCOL_NAMES) HOST = support.HOST @@ -143,6 +144,87 @@ def data_file(*name): OP_ENABLE_MIDDLEBOX_COMPAT = getattr(ssl, "OP_ENABLE_MIDDLEBOX_COMPAT", 0) +def has_tls_protocol(protocol): + """Check if a TLS protocol is available and enabled + + :param protocol: enum ssl._SSLMethod member or name + :return: bool + """ + if isinstance(protocol, str): + assert protocol.startswith('PROTOCOL_') + protocol = getattr(ssl, protocol, None) + if protocol is None: + return False + if protocol in { + ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS_SERVER, + ssl.PROTOCOL_TLS_CLIENT + }: + # auto-negotiate protocols are always available + return True + name = protocol.name + return has_tls_version(name[len('PROTOCOL_'):]) + + +@functools.lru_cache +def has_tls_version(version): + """Check if a TLS/SSL version is enabled + + :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] + + # check compile time flags like ssl.HAS_TLSv1_2 + if not getattr(ssl, f'HAS_{version.name}'): + return False + + # check runtime and dynamic crypto policy settings. A TLS version may + # be compiled in but disabled by a policy or config option. + ctx = ssl.SSLContext() + if ( + hasattr(ctx, 'minimum_version') and + ctx.minimum_version != ssl.TLSVersion.MINIMUM_SUPPORTED and + version < ctx.minimum_version + ): + return False + if ( + hasattr(ctx, 'maximum_version') and + ctx.maximum_version != ssl.TLSVersion.MAXIMUM_SUPPORTED and + version > ctx.maximum_version + ): + return False + + return True + + +def requires_tls_version(version): + """Decorator to skip tests when a required TLS version is not available + + :param version: TLS version name or ssl.TLSVersion member + :return: + """ + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kw): + if not has_tls_version(version): + raise unittest.SkipTest(f"{version} is not available.") + else: + return func(*args, **kw) + return wrapper + return decorator + + +requires_minimum_version = unittest.skipUnless( + hasattr(ssl.SSLContext, 'minimum_version'), + "required OpenSSL >= 1.1.0g" +) + + def handle_error(prefix): exc_format = ' '.join(traceback.format_exception(*sys.exc_info())) if support.verbose: @@ -666,14 +748,19 @@ def fail(cert, hostname): cert = {'subject': ((('commonName', 'example.com'),),), 'subjectAltName': (('DNS', 'example.com'), ('IP Address', '10.11.12.13'), - ('IP Address', '14.15.16.17'))} + ('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 hasattr(socket, 'AF_INET6'): + if support.IPV6_ENABLED: cert = {'subject': ((('commonName', 'example.com'),),), 'subjectAltName': ( ('DNS', 'example.com'), @@ -681,6 +768,8 @@ def fail(cert, hostname): ('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') @@ -754,7 +843,7 @@ def fail(cert, hostname): ssl._inet_paton(invalid) for ipaddr in ['127.0.0.1', '192.168.0.1']: self.assertTrue(ssl._inet_paton(ipaddr)) - if hasattr(socket, 'AF_INET6'): + if support.IPV6_ENABLED: for ipaddr in ['::1', '2001:db8:85a3::8a2e:370:7334']: self.assertTrue(ssl._inet_paton(ipaddr)) @@ -825,8 +914,8 @@ def test_enum_certificates(self): cert, enc, trust = element self.assertIsInstance(cert, bytes) self.assertIn(enc, {"x509_asn", "pkcs_7_asn"}) - self.assertIsInstance(trust, (set, bool)) - if isinstance(trust, set): + self.assertIsInstance(trust, (frozenset, set, bool)) + if isinstance(trust, (frozenset, set)): trust_oids.update(trust) serverAuth = "1.3.6.1.5.5.7.3.1" @@ -1097,19 +1186,23 @@ def test_hostname_checks_common_name(self): with self.assertRaises(AttributeError): ctx.hostname_checks_common_name = True - @unittest.skipUnless(hasattr(ssl.SSLContext, 'minimum_version'), - "required OpenSSL 1.1.0g") + @requires_minimum_version + @unittest.skipIf(IS_LIBRESSL, "see bpo-34001") def test_min_max_version(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) # OpenSSL default is MINIMUM_SUPPORTED, however some vendors like # Fedora override the setting to TLS 1.0. + minimum_range = { + # stock OpenSSL + ssl.TLSVersion.MINIMUM_SUPPORTED, + # Fedora 29 uses TLS 1.0 by default + ssl.TLSVersion.TLSv1, + # RHEL 8 uses TLS 1.2 by default + ssl.TLSVersion.TLSv1_2 + } + self.assertIn( - ctx.minimum_version, - {ssl.TLSVersion.MINIMUM_SUPPORTED, - # Fedora 29 uses TLS 1.0 by default - ssl.TLSVersion.TLSv1, - # RHEL 8 uses TLS 1.2 by default - ssl.TLSVersion.TLSv1_2} + ctx.minimum_version, minimum_range ) self.assertEqual( ctx.maximum_version, ssl.TLSVersion.MAXIMUM_SUPPORTED @@ -1155,8 +1248,8 @@ def test_min_max_version(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_1) - self.assertEqual( - ctx.minimum_version, ssl.TLSVersion.MINIMUM_SUPPORTED + self.assertIn( + ctx.minimum_version, minimum_range ) self.assertEqual( ctx.maximum_version, ssl.TLSVersion.MAXIMUM_SUPPORTED @@ -2709,6 +2802,8 @@ def test_echo(self): for protocol in PROTOCOLS: if protocol in {ssl.PROTOCOL_TLS_CLIENT, ssl.PROTOCOL_TLS_SERVER}: continue + if not has_tls_protocol(protocol): + continue with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]): context = ssl.SSLContext(protocol) context.load_cert_chain(CERTFILE) @@ -3000,7 +3095,7 @@ def test_wrong_cert_tls12(self): else: self.fail("Use of invalid cert should have failed!") - @unittest.skipUnless(ssl.HAS_TLSv1_3, "Test needs TLS 1.3") + @requires_tls_version('TLSv1_3') def test_wrong_cert_tls13(self): client_context, server_context, hostname = testing_context() # load client cert that is not signed by trusted CA @@ -3095,8 +3190,7 @@ def test_ssl_cert_verify_error(self): self.assertIn(msg, repr(e)) self.assertIn('certificate verify failed', repr(e)) - @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'), - "OpenSSL is compiled without SSLv2 support") + @requires_tls_version('SSLv2') def test_protocol_sslv2(self): """Connecting to an SSLv2 server with various client options""" if support.verbose: @@ -3105,7 +3199,7 @@ def test_protocol_sslv2(self): 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 hasattr(ssl, 'PROTOCOL_SSLv3'): + 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 @@ -3122,7 +3216,7 @@ def test_PROTOCOL_TLS(self): """Connecting to an SSLv23 server with various client options""" if support.verbose: sys.stdout.write("\n") - if hasattr(ssl, 'PROTOCOL_SSLv2'): + if has_tls_version('SSLv2'): try: try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv2, True) except OSError as x: @@ -3131,34 +3225,36 @@ def test_PROTOCOL_TLS(self): sys.stdout.write( " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n" % str(x)) - if hasattr(ssl, 'PROTOCOL_SSLv3'): + 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) - try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, 'TLSv1') + if has_tls_version('TLSv1'): + try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, 'TLSv1') - if hasattr(ssl, 'PROTOCOL_SSLv3'): + if has_tls_version('SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS, True, ssl.CERT_OPTIONAL) - try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL) + if has_tls_version('TLSv1'): + try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL) - if hasattr(ssl, 'PROTOCOL_SSLv3'): + if has_tls_version('SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED) try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS, True, ssl.CERT_REQUIRED) - try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED) + if has_tls_version('TLSv1'): + try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED) # Server with specific SSL options - if hasattr(ssl, 'PROTOCOL_SSLv3'): + if has_tls_version('SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv3, False, server_options=ssl.OP_NO_SSLv3) # Will choose TLSv1 try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS, True, server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3) - try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, False, - server_options=ssl.OP_NO_TLSv1) - + if has_tls_version('TLSv1'): + try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, False, + server_options=ssl.OP_NO_TLSv1) - @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'), - "OpenSSL is compiled without SSLv3 support") + @requires_tls_version('SSLv3') def test_protocol_sslv3(self): """Connecting to an SSLv3 server with various client options""" if support.verbose: @@ -3166,7 +3262,7 @@ def test_protocol_sslv3(self): 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 hasattr(ssl, 'PROTOCOL_SSLv2'): + 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) @@ -3176,6 +3272,7 @@ def test_protocol_sslv3(self): try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLS, False, client_options=ssl.OP_NO_SSLv2) + @requires_tls_version('TLSv1') def test_protocol_tlsv1(self): """Connecting to a TLSv1 server with various client options""" if support.verbose: @@ -3183,34 +3280,32 @@ def test_protocol_tlsv1(self): 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 hasattr(ssl, 'PROTOCOL_SSLv2'): + if has_tls_version('SSLv2'): try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False) - if hasattr(ssl, 'PROTOCOL_SSLv3'): + 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, client_options=ssl.OP_NO_TLSv1) - @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"), - "TLS version 1.1 not supported.") + @requires_tls_version('TLSv1_1') def test_protocol_tlsv1_1(self): """Connecting to a TLSv1.1 server with various client options. Testing against older TLS versions.""" if support.verbose: sys.stdout.write("\n") try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1') - if hasattr(ssl, 'PROTOCOL_SSLv2'): + if has_tls_version('SSLv2'): try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False) - if hasattr(ssl, 'PROTOCOL_SSLv3'): + 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, client_options=ssl.OP_NO_TLSv1_1) try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1') - try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False) - try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False) + try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False) + try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False) - @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"), - "TLS version 1.2 not supported.") + @requires_tls_version('TLSv1_2') def test_protocol_tlsv1_2(self): """Connecting to a TLSv1.2 server with various client options. Testing against older TLS versions.""" @@ -3219,9 +3314,9 @@ def test_protocol_tlsv1_2(self): 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 hasattr(ssl, 'PROTOCOL_SSLv2'): + if has_tls_version('SSLv2'): try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False) - if hasattr(ssl, 'PROTOCOL_SSLv3'): + 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) @@ -3664,7 +3759,7 @@ def test_version_basic(self): self.assertIs(s.version(), None) self.assertIs(s._sslobj, None) s.connect((HOST, server.port)) - if IS_OPENSSL_1_1_1 and ssl.HAS_TLSv1_3: + if IS_OPENSSL_1_1_1 and has_tls_version('TLSv1_3'): self.assertEqual(s.version(), 'TLSv1.3') elif ssl.OPENSSL_VERSION_INFO >= (1, 0, 2): self.assertEqual(s.version(), 'TLSv1.2') @@ -3673,8 +3768,7 @@ def test_version_basic(self): self.assertIs(s._sslobj, None) self.assertIs(s.version(), None) - @unittest.skipUnless(ssl.HAS_TLSv1_3, - "test requires TLSv1.3 enabled OpenSSL") + @requires_tls_version('TLSv1_3') def test_tls1_3(self): context = ssl.SSLContext(ssl.PROTOCOL_TLS) context.load_cert_chain(CERTFILE) @@ -3691,9 +3785,9 @@ def test_tls1_3(self): }) self.assertEqual(s.version(), 'TLSv1.3') - @unittest.skipUnless(hasattr(ssl.SSLContext, 'minimum_version'), - "required OpenSSL 1.1.0g") - def test_min_max_version(self): + @requires_minimum_version + @requires_tls_version('TLSv1_2') + def test_min_max_version_tlsv1_2(self): client_context, server_context, hostname = testing_context() # client TLSv1.0 to 1.2 client_context.minimum_version = ssl.TLSVersion.TLSv1 @@ -3708,7 +3802,13 @@ def test_min_max_version(self): s.connect((HOST, server.port)) self.assertEqual(s.version(), 'TLSv1.2') + @requires_minimum_version + @requires_tls_version('TLSv1_1') + def test_min_max_version_tlsv1_1(self): + client_context, server_context, hostname = testing_context() # client 1.0 to 1.2, server 1.0 to 1.1 + client_context.minimum_version = ssl.TLSVersion.TLSv1 + client_context.maximum_version = ssl.TLSVersion.TLSv1_2 server_context.minimum_version = ssl.TLSVersion.TLSv1 server_context.maximum_version = ssl.TLSVersion.TLSv1_1 @@ -3718,11 +3818,15 @@ def test_min_max_version(self): s.connect((HOST, server.port)) self.assertEqual(s.version(), 'TLSv1.1') + @requires_minimum_version + @requires_tls_version('TLSv1_2') + def test_min_max_version_mismatch(self): + client_context, server_context, hostname = testing_context() # client 1.0, server 1.2 (mismatch) - server_context.minimum_version = ssl.TLSVersion.TLSv1_2 server_context.maximum_version = ssl.TLSVersion.TLSv1_2 + server_context.minimum_version = ssl.TLSVersion.TLSv1_2 client_context.maximum_version = ssl.TLSVersion.TLSv1 - client_context.maximum_version = ssl.TLSVersion.TLSv1 + client_context.minimum_version = ssl.TLSVersion.TLSv1 with ThreadedEchoServer(context=server_context) as server: with client_context.wrap_socket(socket.socket(), server_hostname=hostname) as s: @@ -3730,10 +3834,8 @@ def test_min_max_version(self): s.connect((HOST, server.port)) self.assertIn("alert", str(e.exception)) - - @unittest.skipUnless(hasattr(ssl.SSLContext, 'minimum_version'), - "required OpenSSL 1.1.0g") - @unittest.skipUnless(ssl.HAS_SSLv3, "requires SSLv3 support") + @requires_minimum_version + @requires_tls_version('SSLv3') def test_min_max_version_sslv3(self): client_context, server_context, hostname = testing_context() server_context.minimum_version = ssl.TLSVersion.SSLv3 @@ -4256,7 +4358,7 @@ def test_session_handling(self): 'Session refers to a different SSLContext.') -@unittest.skipUnless(ssl.HAS_TLSv1_3, "Test needs TLS 1.3") +@unittest.skipUnless(has_tls_version('TLSv1_3'), "Test needs TLS 1.3") class TestPostHandshakeAuth(unittest.TestCase): def test_pha_setter(self): protocols = [ @@ -4313,21 +4415,24 @@ def test_pha_required_nocert(self): server_context.verify_mode = ssl.CERT_REQUIRED client_context.post_handshake_auth = True - server = ThreadedEchoServer(context=server_context, chatty=False) - with server: - with client_context.wrap_socket(socket.socket(), - server_hostname=hostname) as s: - s.connect((HOST, server.port)) - s.write(b'PHA') - # receive CertificateRequest - self.assertEqual(s.recv(1024), b'OK\n') - # send empty Certificate + Finish - s.write(b'HASCERT') - # receive alert - with self.assertRaisesRegex( - ssl.SSLError, - 'tlsv13 alert certificate required'): - s.recv(1024) + # Ignore expected SSLError in ConnectionHandler of ThreadedEchoServer + # (it is only raised sometimes on Windows) + with support.catch_threading_exception() as cm: + server = ThreadedEchoServer(context=server_context, chatty=False) + with server: + with client_context.wrap_socket(socket.socket(), + server_hostname=hostname) as s: + s.connect((HOST, server.port)) + s.write(b'PHA') + # receive CertificateRequest + self.assertEqual(s.recv(1024), b'OK\n') + # send empty Certificate + Finish + s.write(b'HASCERT') + # receive alert + with self.assertRaisesRegex( + ssl.SSLError, + 'tlsv13 alert certificate required'): + s.recv(1024) def test_pha_optional(self): if support.verbose: @@ -4428,6 +4533,37 @@ def test_pha_not_tls13(self): s.write(b'PHA') self.assertIn(b'WRONG_SSL_VERSION', s.recv(1024)) + def test_bpo37428_pha_cert_none(self): + # verify that post_handshake_auth does not implicitly enable cert + # validation. + hostname = SIGNED_CERTFILE_HOSTNAME + client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + client_context.post_handshake_auth = True + client_context.load_cert_chain(SIGNED_CERTFILE) + # no cert validation and CA on client side + client_context.check_hostname = False + client_context.verify_mode = ssl.CERT_NONE + + server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + server_context.load_cert_chain(SIGNED_CERTFILE) + server_context.load_verify_locations(SIGNING_CA) + server_context.post_handshake_auth = True + server_context.verify_mode = ssl.CERT_REQUIRED + + server = ThreadedEchoServer(context=server_context, chatty=False) + with server: + with client_context.wrap_socket(socket.socket(), + server_hostname=hostname) as s: + s.connect((HOST, server.port)) + s.write(b'HASCERT') + self.assertEqual(s.recv(1024), b'FALSE\n') + s.write(b'PHA') + self.assertEqual(s.recv(1024), b'OK\n') + s.write(b'HASCERT') + self.assertEqual(s.recv(1024), b'TRUE\n') + # server cert has not been validated + self.assertEqual(s.getpeercert(), {}) + HAS_KEYLOG = hasattr(ssl.SSLContext, 'keylog_filename') requires_keylog = unittest.skipUnless( @@ -4561,7 +4697,6 @@ def msg_cb(conn, direction, version, content_type, msg_type, data): def test_main(verbose=False): if support.verbose: - import warnings plats = { 'Mac': platform.mac_ver, 'Windows': platform.win32_ver, diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py index 17443bed0738b5..be01db2ed55746 100644 --- a/Lib/test/test_stat.py +++ b/Lib/test/test_stat.py @@ -16,10 +16,10 @@ class TestFilemode: 'UF_IMMUTABLE', 'UF_NODUMP', 'UF_NOUNLINK', 'UF_OPAQUE'} formats = {'S_IFBLK', 'S_IFCHR', 'S_IFDIR', 'S_IFIFO', 'S_IFLNK', - 'S_IFREG', 'S_IFSOCK'} + 'S_IFREG', 'S_IFSOCK', 'S_IFDOOR', 'S_IFPORT', 'S_IFWHT'} format_funcs = {'S_ISBLK', 'S_ISCHR', 'S_ISDIR', 'S_ISFIFO', 'S_ISLNK', - 'S_ISREG', 'S_ISSOCK'} + 'S_ISREG', 'S_ISSOCK', 'S_ISDOOR', 'S_ISPORT', 'S_ISWHT'} stat_struct = { 'ST_MODE': 0, @@ -231,10 +231,6 @@ def test_file_attribute_constants(self): class TestFilemodeCStat(TestFilemode, unittest.TestCase): statmod = c_stat - formats = TestFilemode.formats | {'S_IFDOOR', 'S_IFPORT', 'S_IFWHT'} - format_funcs = TestFilemode.format_funcs | {'S_ISDOOR', 'S_ISPORT', - 'S_ISWHT'} - class TestFilemodePyStat(TestFilemode, unittest.TestCase): statmod = py_stat diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index 946c7428c61311..bebd9b5d6f5026 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -14,9 +14,11 @@ import random import sys import unittest +from test import support from decimal import Decimal from fractions import Fraction +from test import support # Module to be tested. @@ -177,6 +179,23 @@ class _DoNothing: # We prefer this for testing numeric values that may not be exactly equal, # and avoid using TestCase.assertAlmostEqual, because it sucks :-) +py_statistics = support.import_fresh_module('statistics', blocked=['_statistics']) +c_statistics = support.import_fresh_module('statistics', fresh=['_statistics']) + + +class TestModules(unittest.TestCase): + func_names = ['_normal_dist_inv_cdf'] + + def test_py_functions(self): + for fname in self.func_names: + self.assertEqual(getattr(py_statistics, fname).__module__, 'statistics') + + @unittest.skipUnless(c_statistics, 'requires _statistics') + def test_c_functions(self): + for fname in self.func_names: + self.assertEqual(getattr(c_statistics, fname).__module__, '_statistics') + + class NumericTestCase(unittest.TestCase): """Unit test class for numeric work. @@ -1791,13 +1810,13 @@ def test_bimodal_data(self): # Test mode with bimodal data. data = [1, 1, 2, 2, 2, 2, 3, 4, 5, 6, 6, 6, 6, 7, 8, 9, 9] assert data.count(2) == data.count(6) == 4 - # mode() should return 2, the first encounted mode + # mode() should return 2, the first encountered mode self.assertEqual(self.func(data), 2) def test_unique_data(self): # Test mode when data points are all unique. data = list(range(10)) - # mode() should return 0, the first encounted mode + # mode() should return 0, the first encountered mode self.assertEqual(self.func(data), 0) def test_none_data(self): @@ -2179,16 +2198,6 @@ def f(x): exp = list(map(f, expected)) act = quantiles(map(f, data), n=n) self.assertTrue(all(math.isclose(e, a) for e, a in zip(exp, act))) - # Quartiles of a standard normal distribution - for n, expected in [ - (1, []), - (2, [0.0]), - (3, [-0.4307, 0.4307]), - (4 ,[-0.6745, 0.0, 0.6745]), - ]: - actual = quantiles(statistics.NormalDist(), n=n) - self.assertTrue(all(math.isclose(e, a, abs_tol=0.0001) - for e, a in zip(expected, actual))) # Q2 agrees with median() for k in range(2, 60): data = random.choices(range(100), k=k) @@ -2229,16 +2238,6 @@ def f(x): exp = list(map(f, expected)) act = quantiles(map(f, data), n=n, method="inclusive") self.assertTrue(all(math.isclose(e, a) for e, a in zip(exp, act))) - # Quartiles of a standard normal distribution - for n, expected in [ - (1, []), - (2, [0.0]), - (3, [-0.4307, 0.4307]), - (4 ,[-0.6745, 0.0, 0.6745]), - ]: - actual = quantiles(statistics.NormalDist(), n=n, method="inclusive") - self.assertTrue(all(math.isclose(e, a, abs_tol=0.0001) - for e, a in zip(expected, actual))) # Natural deciles self.assertEqual(quantiles([0, 100], n=10, method='inclusive'), [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0]) @@ -2313,7 +2312,7 @@ def test_error_cases(self): quantiles([10, None, 30], n=4) # data is non-numeric -class TestNormalDist(unittest.TestCase): +class TestNormalDist: # General note on precision: The pdf(), cdf(), and overlap() methods # depend on functions in the math libraries that do not make @@ -2323,35 +2322,35 @@ class TestNormalDist(unittest.TestCase): # implementing our own implementations from scratch. def test_slots(self): - nd = statistics.NormalDist(300, 23) + nd = self.module.NormalDist(300, 23) with self.assertRaises(TypeError): vars(nd) - self.assertEqual(tuple(nd.__slots__), ('mu', 'sigma')) + self.assertEqual(tuple(nd.__slots__), ('_mu', '_sigma')) def test_instantiation_and_attributes(self): - nd = statistics.NormalDist(500, 17) - self.assertEqual(nd.mu, 500) - self.assertEqual(nd.sigma, 17) + nd = self.module.NormalDist(500, 17) + self.assertEqual(nd.mean, 500) + self.assertEqual(nd.stdev, 17) self.assertEqual(nd.variance, 17**2) # default arguments - nd = statistics.NormalDist() - self.assertEqual(nd.mu, 0) - self.assertEqual(nd.sigma, 1) + nd = self.module.NormalDist() + self.assertEqual(nd.mean, 0) + self.assertEqual(nd.stdev, 1) self.assertEqual(nd.variance, 1**2) # error case: negative sigma - with self.assertRaises(statistics.StatisticsError): - statistics.NormalDist(500, -10) + with self.assertRaises(self.module.StatisticsError): + self.module.NormalDist(500, -10) # verify that subclass type is honored - class NewNormalDist(statistics.NormalDist): + class NewNormalDist(self.module.NormalDist): pass nnd = NewNormalDist(200, 5) self.assertEqual(type(nnd), NewNormalDist) def test_alternative_constructor(self): - NormalDist = statistics.NormalDist + NormalDist = self.module.NormalDist data = [96, 107, 90, 92, 110] # list input self.assertEqual(NormalDist.from_samples(data), NormalDist(99, 9)) @@ -2360,9 +2359,9 @@ def test_alternative_constructor(self): # iterator input self.assertEqual(NormalDist.from_samples(iter(data)), NormalDist(99, 9)) # error cases - with self.assertRaises(statistics.StatisticsError): + with self.assertRaises(self.module.StatisticsError): NormalDist.from_samples([]) # empty input - with self.assertRaises(statistics.StatisticsError): + with self.assertRaises(self.module.StatisticsError): NormalDist.from_samples([10]) # only one input # verify that subclass type is honored @@ -2372,7 +2371,7 @@ class NewNormalDist(NormalDist): self.assertEqual(type(nnd), NewNormalDist) def test_sample_generation(self): - NormalDist = statistics.NormalDist + NormalDist = self.module.NormalDist mu, sigma = 10_000, 3.0 X = NormalDist(mu, sigma) n = 1_000 @@ -2380,7 +2379,7 @@ def test_sample_generation(self): self.assertEqual(len(data), n) self.assertEqual(set(map(type, data)), {float}) # mean(data) expected to fall within 8 standard deviations - xbar = statistics.mean(data) + xbar = self.module.mean(data) self.assertTrue(mu - sigma*8 <= xbar <= mu + sigma*8) # verify that seeding makes reproducible sequences @@ -2394,7 +2393,7 @@ def test_sample_generation(self): self.assertNotEqual(data1, data2) def test_pdf(self): - NormalDist = statistics.NormalDist + NormalDist = self.module.NormalDist X = NormalDist(100, 15) # Verify peak around center self.assertLess(X.pdf(99), X.pdf(100)) @@ -2425,7 +2424,7 @@ def test_pdf(self): self.assertAlmostEqual(Z.pdf(-x / 100.0), px, places=4) # Error case: variance is zero Y = NormalDist(100, 0) - with self.assertRaises(statistics.StatisticsError): + with self.assertRaises(self.module.StatisticsError): Y.pdf(90) # Special values self.assertEqual(X.pdf(float('-Inf')), 0.0) @@ -2433,7 +2432,7 @@ def test_pdf(self): self.assertTrue(math.isnan(X.pdf(float('NaN')))) def test_cdf(self): - NormalDist = statistics.NormalDist + NormalDist = self.module.NormalDist X = NormalDist(100, 15) cdfs = [X.cdf(x) for x in range(1, 200)] self.assertEqual(set(map(type, cdfs)), {float}) @@ -2455,15 +2454,16 @@ def test_cdf(self): self.assertAlmostEqual(Z.cdf(-z), 1.0 - cum_prob, places=5) # Error case: variance is zero Y = NormalDist(100, 0) - with self.assertRaises(statistics.StatisticsError): + with self.assertRaises(self.module.StatisticsError): Y.cdf(90) # Special values self.assertEqual(X.cdf(float('-Inf')), 0.0) self.assertEqual(X.cdf(float('Inf')), 1.0) self.assertTrue(math.isnan(X.cdf(float('NaN')))) + @support.skip_if_pgo_task def test_inv_cdf(self): - NormalDist = statistics.NormalDist + NormalDist = self.module.NormalDist # Center case should be exact. iq = NormalDist(100, 15) @@ -2511,26 +2511,36 @@ def test_inv_cdf(self): self.assertAlmostEqual(iq.inv_cdf(iq.cdf(x)), x, places=5) # Error cases: - with self.assertRaises(statistics.StatisticsError): + with self.assertRaises(self.module.StatisticsError): iq.inv_cdf(0.0) # p is zero - with self.assertRaises(statistics.StatisticsError): + with self.assertRaises(self.module.StatisticsError): iq.inv_cdf(-0.1) # p under zero - with self.assertRaises(statistics.StatisticsError): + with self.assertRaises(self.module.StatisticsError): iq.inv_cdf(1.0) # p is one - with self.assertRaises(statistics.StatisticsError): + with self.assertRaises(self.module.StatisticsError): iq.inv_cdf(1.1) # p over one - with self.assertRaises(statistics.StatisticsError): - iq.sigma = 0.0 # sigma is zero - iq.inv_cdf(0.5) - with self.assertRaises(statistics.StatisticsError): - iq.sigma = -0.1 # sigma under zero + with self.assertRaises(self.module.StatisticsError): + iq = NormalDist(100, 0) # sigma is zero iq.inv_cdf(0.5) # Special values self.assertTrue(math.isnan(Z.inv_cdf(float('NaN')))) + def test_quantiles(self): + # Quartiles of a standard normal distribution + Z = self.module.NormalDist() + for n, expected in [ + (1, []), + (2, [0.0]), + (3, [-0.4307, 0.4307]), + (4 ,[-0.6745, 0.0, 0.6745]), + ]: + actual = Z.quantiles(n=n) + self.assertTrue(all(math.isclose(e, a, abs_tol=0.0001) + for e, a in zip(expected, actual))) + def test_overlap(self): - NormalDist = statistics.NormalDist + NormalDist = self.module.NormalDist # Match examples from Imman and Bradley for X1, X2, published_result in [ @@ -2544,8 +2554,8 @@ def test_overlap(self): def overlap_numeric(X, Y, *, steps=8_192, z=5): 'Numerical integration cross-check for overlap() ' fsum = math.fsum - center = (X.mu + Y.mu) / 2.0 - width = z * max(X.sigma, Y.sigma) + center = (X.mean + Y.mean) / 2.0 + width = z * max(X.stdev, Y.stdev) start = center - width dx = 2.0 * width / steps x_arr = [start + i*dx for i in range(steps)] @@ -2587,26 +2597,28 @@ def overlap_numeric(X, Y, *, steps=8_192, z=5): X.overlap(X, X) # too may arguments with self.assertRaises(TypeError): X.overlap(None) # right operand not a NormalDist - with self.assertRaises(statistics.StatisticsError): + with self.assertRaises(self.module.StatisticsError): X.overlap(NormalDist(1, 0)) # right operand sigma is zero - with self.assertRaises(statistics.StatisticsError): + with self.assertRaises(self.module.StatisticsError): NormalDist(1, 0).overlap(X) # left operand sigma is zero def test_properties(self): - X = statistics.NormalDist(100, 15) + X = self.module.NormalDist(100, 15) self.assertEqual(X.mean, 100) + self.assertEqual(X.median, 100) + self.assertEqual(X.mode, 100) self.assertEqual(X.stdev, 15) self.assertEqual(X.variance, 225) def test_same_type_addition_and_subtraction(self): - NormalDist = statistics.NormalDist + NormalDist = self.module.NormalDist X = NormalDist(100, 12) Y = NormalDist(40, 5) self.assertEqual(X + Y, NormalDist(140, 13)) # __add__ self.assertEqual(X - Y, NormalDist(60, 13)) # __sub__ def test_translation_and_scaling(self): - NormalDist = statistics.NormalDist + NormalDist = self.module.NormalDist X = NormalDist(100, 15) y = 10 self.assertEqual(+X, NormalDist(100, 15)) # __pos__ @@ -2622,26 +2634,30 @@ def test_translation_and_scaling(self): y / X def test_unary_operations(self): - NormalDist = statistics.NormalDist + NormalDist = self.module.NormalDist X = NormalDist(100, 12) Y = +X self.assertIsNot(X, Y) - self.assertEqual(X.mu, Y.mu) - self.assertEqual(X.sigma, Y.sigma) + self.assertEqual(X.mean, Y.mean) + self.assertEqual(X.stdev, Y.stdev) Y = -X self.assertIsNot(X, Y) - self.assertEqual(X.mu, -Y.mu) - self.assertEqual(X.sigma, Y.sigma) + self.assertEqual(X.mean, -Y.mean) + self.assertEqual(X.stdev, Y.stdev) def test_equality(self): - NormalDist = statistics.NormalDist + NormalDist = self.module.NormalDist nd1 = NormalDist() nd2 = NormalDist(2, 4) nd3 = NormalDist() nd4 = NormalDist(2, 4) + nd5 = NormalDist(2, 8) + nd6 = NormalDist(8, 4) self.assertNotEqual(nd1, nd2) self.assertEqual(nd1, nd3) self.assertEqual(nd2, nd4) + self.assertNotEqual(nd2, nd5) + self.assertNotEqual(nd2, nd6) # Test NotImplemented when types are different class A: @@ -2674,7 +2690,7 @@ def __init__(self, mu, sigma): self.assertNotEqual(nd, lnd) def test_pickle_and_copy(self): - nd = statistics.NormalDist(37.5, 5.625) + nd = self.module.NormalDist(37.5, 5.625) nd1 = copy.copy(nd) self.assertEqual(nd, nd1) nd2 = copy.deepcopy(nd) @@ -2682,10 +2698,37 @@ def test_pickle_and_copy(self): nd3 = pickle.loads(pickle.dumps(nd)) self.assertEqual(nd, nd3) + def test_hashability(self): + ND = self.module.NormalDist + s = {ND(100, 15), ND(100.0, 15.0), ND(100, 10), ND(95, 15), ND(100, 15)} + self.assertEqual(len(s), 3) + def test_repr(self): - nd = statistics.NormalDist(37.5, 5.625) + nd = self.module.NormalDist(37.5, 5.625) self.assertEqual(repr(nd), 'NormalDist(mu=37.5, sigma=5.625)') +# Swapping the sys.modules['statistics'] is to solving the +# _pickle.PicklingError: +# Can't pickle : +# it's not the same object as statistics.NormalDist +class TestNormalDistPython(unittest.TestCase, TestNormalDist): + module = py_statistics + def setUp(self): + sys.modules['statistics'] = self.module + + def tearDown(self): + sys.modules['statistics'] = statistics + + +@unittest.skipUnless(c_statistics, 'requires _statistics') +class TestNormalDistC(unittest.TestCase, TestNormalDist): + module = c_statistics + def setUp(self): + sys.modules['statistics'] = self.module + + def tearDown(self): + sys.modules['statistics'] = statistics + # === Run tests === diff --git a/Lib/test/test_string_literals.py b/Lib/test/test_string_literals.py index 048f40d90a4bb7..0cea2edc32afa2 100644 --- a/Lib/test/test_string_literals.py +++ b/Lib/test/test_string_literals.py @@ -31,8 +31,8 @@ import sys import shutil import tempfile -import warnings import unittest +import warnings TEMPLATE = r"""# coding: %s @@ -111,10 +111,24 @@ def test_eval_str_invalid_escape(self): for b in range(1, 128): if b in b"""\n\r"'01234567NU\\abfnrtuvx""": continue - with self.assertWarns(SyntaxWarning): + with self.assertWarns(DeprecationWarning): self.assertEqual(eval(r"'\%c'" % b), '\\' + chr(b)) - self.check_syntax_warning("'''\n\\z'''") + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always', category=DeprecationWarning) + eval("'''\n\\z'''") + self.assertEqual(len(w), 1) + self.assertEqual(w[0].filename, '') + self.assertEqual(w[0].lineno, 1) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('error', category=DeprecationWarning) + with self.assertRaises(SyntaxError) as cm: + eval("'''\n\\z'''") + exc = cm.exception + self.assertEqual(w, []) + self.assertEqual(exc.filename, '') + self.assertEqual(exc.lineno, 1) def test_eval_str_raw(self): self.assertEqual(eval(""" r'x' """), 'x') @@ -146,10 +160,24 @@ def test_eval_bytes_invalid_escape(self): for b in range(1, 128): if b in b"""\n\r"'01234567\\abfnrtvx""": continue - with self.assertWarns(SyntaxWarning): + with self.assertWarns(DeprecationWarning): self.assertEqual(eval(r"b'\%c'" % b), b'\\' + bytes([b])) - self.check_syntax_warning("b'''\n\\z'''") + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always', category=DeprecationWarning) + eval("b'''\n\\z'''") + self.assertEqual(len(w), 1) + self.assertEqual(w[0].filename, '') + self.assertEqual(w[0].lineno, 1) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('error', category=DeprecationWarning) + with self.assertRaises(SyntaxError) as cm: + eval("b'''\n\\z'''") + exc = cm.exception + self.assertEqual(w, []) + self.assertEqual(exc.filename, '') + self.assertEqual(exc.lineno, 1) def test_eval_bytes_raw(self): self.assertEqual(eval(""" br'x' """), b'x') diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 623da401eee4ff..55a0f426731a5d 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -7,6 +7,7 @@ import os import sys from test import support +from test.support import skip_if_buggy_ucrt_strfptime from datetime import date as datetime_date import _strptime @@ -135,6 +136,7 @@ def test_pattern_escaping(self): "%s does not have re characters escaped properly" % pattern_string) + @skip_if_buggy_ucrt_strfptime def test_compile(self): # Check that compiled regex is correct found = self.time_re.compile(r"%A").match(self.locale_time.f_weekday[6]) @@ -365,6 +367,7 @@ def test_bad_offset(self): _strptime._strptime("-01:3030", "%z") self.assertEqual("Inconsistent use of : in -01:3030", str(err.exception)) + @skip_if_buggy_ucrt_strfptime def test_timezone(self): # Test timezone directives. # When gmtime() is used with %Z, entire result of strftime() is empty. @@ -489,6 +492,7 @@ class CalculationTests(unittest.TestCase): def setUp(self): self.time_tuple = time.gmtime() + @skip_if_buggy_ucrt_strfptime def test_julian_calculation(self): # Make sure that when Julian is missing that it is calculated format_string = "%Y %m %d %H %M %S %w %Z" @@ -498,6 +502,7 @@ def test_julian_calculation(self): "Calculation of tm_yday failed; %s != %s" % (result.tm_yday, self.time_tuple.tm_yday)) + @skip_if_buggy_ucrt_strfptime def test_gregorian_calculation(self): # Test that Gregorian date can be calculated from Julian day format_string = "%Y %H %M %S %w %j %Z" @@ -512,6 +517,7 @@ def test_gregorian_calculation(self): self.time_tuple.tm_year, self.time_tuple.tm_mon, self.time_tuple.tm_mday)) + @skip_if_buggy_ucrt_strfptime def test_day_of_week_calculation(self): # Test that the day of the week is calculated as needed format_string = "%Y %m %d %H %S %j %Z" diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index fca3ed62099bde..b2afd127dfed87 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -3,7 +3,6 @@ from test import support import subprocess import sys -import platform import signal import io import itertools @@ -11,6 +10,7 @@ import errno import tempfile import time +import traceback import selectors import sysconfig import select @@ -20,18 +20,12 @@ import textwrap from test.support import FakePath -try: - import ctypes -except ImportError: - ctypes = None -else: - import ctypes.util - try: import _testcapi except ImportError: _testcapi = None + if support.PGO: raise unittest.SkipTest("test is not helpful for PGO") @@ -51,6 +45,18 @@ # Ignore errors that indicate the command was not found NONEXISTING_ERRORS = (FileNotFoundError, NotADirectoryError, PermissionError) +ZERO_RETURN_CMD = (sys.executable, '-c', 'pass') + + +def setUpModule(): + shell_true = shutil.which('true') + if shell_true is None: + return + if (os.access(shell_true, os.X_OK) and + subprocess.run([shell_true]).returncode == 0): + global ZERO_RETURN_CMD + ZERO_RETURN_CMD = (shell_true,) # Faster than Python startup. + class BaseTestCase(unittest.TestCase): def setUp(self): @@ -59,10 +65,14 @@ def setUp(self): support.reap_children() def tearDown(self): - for inst in subprocess._active: - inst.wait() - subprocess._cleanup() - self.assertFalse(subprocess._active, "subprocess._active not empty") + if not mswindows: + # subprocess._active is not used on Windows and is set to None. + for inst in subprocess._active: + inst.wait() + subprocess._cleanup() + self.assertFalse( + subprocess._active, "subprocess._active not empty" + ) self.doCleanups() support.reap_children() @@ -91,7 +101,7 @@ def _execute_child(self, *args, **kwargs): class ProcessTestCase(BaseTestCase): def test_io_buffered_by_default(self): - p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"], + p = subprocess.Popen(ZERO_RETURN_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) try: @@ -105,7 +115,7 @@ def test_io_buffered_by_default(self): p.wait() def test_io_unbuffered_works(self): - p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"], + p = subprocess.Popen(ZERO_RETURN_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0) try: @@ -135,8 +145,7 @@ def test_call_timeout(self): def test_check_call_zero(self): # check_call() function with zero return code - rc = subprocess.check_call([sys.executable, "-c", - "import sys; sys.exit(0)"]) + rc = subprocess.check_call(ZERO_RETURN_CMD) self.assertEqual(rc, 0) def test_check_call_nonzero(self): @@ -702,19 +711,19 @@ def test_invalid_env(self): newenv = os.environ.copy() newenv["FRUIT\0VEGETABLE"] = "cabbage" with self.assertRaises(ValueError): - subprocess.Popen([sys.executable, "-c", "pass"], env=newenv) + subprocess.Popen(ZERO_RETURN_CMD, env=newenv) # null character in the environment variable value newenv = os.environ.copy() newenv["FRUIT"] = "orange\0VEGETABLE=cabbage" with self.assertRaises(ValueError): - subprocess.Popen([sys.executable, "-c", "pass"], env=newenv) + subprocess.Popen(ZERO_RETURN_CMD, env=newenv) # equal character in the environment variable name newenv = os.environ.copy() newenv["FRUIT=ORANGE"] = "lemon" with self.assertRaises(ValueError): - subprocess.Popen([sys.executable, "-c", "pass"], env=newenv) + subprocess.Popen(ZERO_RETURN_CMD, env=newenv) # equal character in the environment variable value newenv = os.environ.copy() @@ -815,7 +824,7 @@ def test_communicate_pipe_fd_leak(self): options['stderr'] = subprocess.PIPE if not options: continue - p = subprocess.Popen((sys.executable, "-c", "pass"), **options) + p = subprocess.Popen(ZERO_RETURN_CMD, **options) p.communicate() if p.stdin is not None: self.assertTrue(p.stdin.closed) @@ -954,7 +963,7 @@ def test_universal_newlines_communicate_input_none(self): # # We set stdout to PIPE because, as of this writing, a different # code path is tested when the number of pipes is zero or one. - p = subprocess.Popen([sys.executable, "-c", "pass"], + p = subprocess.Popen(ZERO_RETURN_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) @@ -1102,7 +1111,7 @@ def test_poll(self): self.assertEqual(p.poll(), 0) def test_wait(self): - p = subprocess.Popen([sys.executable, "-c", "pass"]) + p = subprocess.Popen(ZERO_RETURN_CMD) self.assertEqual(p.wait(), 0) # Subsequent invocations should just return the returncode self.assertEqual(p.wait(), 0) @@ -1121,14 +1130,14 @@ def test_invalid_bufsize(self): # an invalid type of the bufsize argument should raise # TypeError. with self.assertRaises(TypeError): - subprocess.Popen([sys.executable, "-c", "pass"], "orange") + subprocess.Popen(ZERO_RETURN_CMD, "orange") def test_bufsize_is_none(self): # bufsize=None should be the same as bufsize=0. - p = subprocess.Popen([sys.executable, "-c", "pass"], None) + p = subprocess.Popen(ZERO_RETURN_CMD, None) self.assertEqual(p.wait(), 0) # Again with keyword arg - p = subprocess.Popen([sys.executable, "-c", "pass"], bufsize=None) + p = subprocess.Popen(ZERO_RETURN_CMD, bufsize=None) self.assertEqual(p.wait(), 0) def _test_bufsize_equal_one(self, line, expected, universal_newlines): @@ -1333,7 +1342,7 @@ def test_handles_closed_on_exception(self): def test_communicate_epipe(self): # Issue 10963: communicate() should hide EPIPE - p = subprocess.Popen([sys.executable, "-c", 'pass'], + p = subprocess.Popen(ZERO_RETURN_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -1344,7 +1353,7 @@ def test_communicate_epipe(self): def test_communicate_epipe_only_stdin(self): # Issue 10963: communicate() should hide EPIPE - p = subprocess.Popen([sys.executable, "-c", 'pass'], + p = subprocess.Popen(ZERO_RETURN_CMD, stdin=subprocess.PIPE) self.addCleanup(p.stdin.close) p.wait() @@ -1383,7 +1392,7 @@ def test_failed_child_execute_fd_leak(self): fds_before_popen = os.listdir(fd_directory) with self.assertRaises(PopenTestException): PopenExecuteChildRaises( - [sys.executable, '-c', 'pass'], stdin=subprocess.PIPE, + ZERO_RETURN_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # NOTE: This test doesn't verify that the real _execute_child @@ -1426,7 +1435,7 @@ def test_check(self): def test_check_zero(self): # check_returncode shouldn't raise when returncode is zero - cp = self.run_python("import sys; sys.exit(0)", check=True) + cp = subprocess.run(ZERO_RETURN_CMD, check=True) self.assertEqual(cp.returncode, 0) def test_timeout(self): @@ -1560,6 +1569,26 @@ def test_stderr_with_capture_output_arg(self): self.assertIn('stderr', c.exception.args[0]) self.assertIn('capture_output', c.exception.args[0]) + # This test _might_ wind up a bit fragile on loaded build+test machines + # as it depends on the timing with wide enough margins for normal situations + # but does assert that it happened "soon enough" to believe the right thing + # happened. + @unittest.skipIf(mswindows, "requires posix like 'sleep' shell command") + def test_run_with_shell_timeout_and_capture_output(self): + """Output capturing after a timeout mustn't hang forever on open filehandles.""" + before_secs = time.monotonic() + try: + subprocess.run('sleep 3', shell=True, timeout=0.1, + capture_output=True) # New session unspecified. + except subprocess.TimeoutExpired as exc: + after_secs = time.monotonic() + stacks = traceback.format_exc() # assertRaises doesn't give this. + else: + self.fail("TimeoutExpired not raised.") + self.assertLess(after_secs - before_secs, 1.5, + msg="TimeoutExpired was delayed! Bad traceback:\n```\n" + f"{stacks}```") + @unittest.skipIf(mswindows, "POSIX specific tests") class POSIXProcessTestCase(BaseTestCase): @@ -1705,16 +1734,15 @@ def test_start_new_session(self): # still indicates that it was called. try: output = subprocess.check_output( - [sys.executable, "-c", - "import os; print(os.getpgid(os.getpid()))"], + [sys.executable, "-c", "import os; print(os.getsid(0))"], start_new_session=True) except OSError as e: if e.errno != errno.EPERM: raise else: - parent_pgid = os.getpgid(os.getpid()) - child_pgid = int(output) - self.assertNotEqual(parent_pgid, child_pgid) + parent_sid = os.getsid(0) + child_sid = int(output) + self.assertNotEqual(parent_sid, child_sid) def test_run_abort(self): # returncode handles signal termination @@ -1807,7 +1835,7 @@ def raise_it(): with self.assertRaises(subprocess.SubprocessError): self._TestExecuteChildPopen( - self, [sys.executable, "-c", "pass"], + self, ZERO_RETURN_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=raise_it) @@ -2264,7 +2292,7 @@ def prepare(): try: subprocess.call( - [sys.executable, "-c", "pass"], + ZERO_RETURN_CMD, preexec_fn=prepare) except ValueError as err: # Pure Python implementations keeps the message @@ -2307,29 +2335,30 @@ def test_undecodable_env(self): self.assertEqual(stdout.decode('ascii'), ascii(encoded_value)) def test_bytes_program(self): - abs_program = os.fsencode(sys.executable) - path, program = os.path.split(sys.executable) + abs_program = os.fsencode(ZERO_RETURN_CMD[0]) + args = list(ZERO_RETURN_CMD[1:]) + path, program = os.path.split(ZERO_RETURN_CMD[0]) program = os.fsencode(program) # absolute bytes path - exitcode = subprocess.call([abs_program, "-c", "pass"]) + exitcode = subprocess.call([abs_program]+args) self.assertEqual(exitcode, 0) # absolute bytes path as a string - cmd = b"'" + abs_program + b"' -c pass" + cmd = b"'%s' %s" % (abs_program, " ".join(args).encode("utf-8")) exitcode = subprocess.call(cmd, shell=True) self.assertEqual(exitcode, 0) # bytes program, unicode PATH env = os.environ.copy() env["PATH"] = path - exitcode = subprocess.call([program, "-c", "pass"], env=env) + exitcode = subprocess.call([program]+args, env=env) self.assertEqual(exitcode, 0) # bytes program, bytes PATH envb = os.environb.copy() envb[b"PATH"] = os.fsencode(path) - exitcode = subprocess.call([program, "-c", "pass"], env=envb) + exitcode = subprocess.call([program]+args, env=envb) self.assertEqual(exitcode, 0) def test_pipe_cloexec(self): @@ -2557,7 +2586,7 @@ def test_pass_fds(self): # pass_fds overrides close_fds with a warning. with self.assertWarns(RuntimeWarning) as context: self.assertFalse(subprocess.call( - [sys.executable, "-c", "import sys; sys.exit(0)"], + ZERO_RETURN_CMD, close_fds=False, pass_fds=(fd, ))) self.assertIn('overriding close_fds', str(context.warning)) @@ -2619,19 +2648,19 @@ def test_pass_fds_redirected(self): def test_stdout_stdin_are_single_inout_fd(self): with io.open(os.devnull, "r+") as inout: - p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"], + p = subprocess.Popen(ZERO_RETURN_CMD, stdout=inout, stdin=inout) p.wait() def test_stdout_stderr_are_single_inout_fd(self): with io.open(os.devnull, "r+") as inout: - p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"], + p = subprocess.Popen(ZERO_RETURN_CMD, stdout=inout, stderr=inout) p.wait() def test_stderr_stdin_are_single_inout_fd(self): with io.open(os.devnull, "r+") as inout: - p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"], + p = subprocess.Popen(ZERO_RETURN_CMD, stderr=inout, stdin=inout) p.wait() @@ -2680,8 +2709,12 @@ def test_zombie_fast_process_del(self): with support.check_warnings(('', ResourceWarning)): p = None - # check that p is in the active processes list - self.assertIn(ident, [id(o) for o in subprocess._active]) + if mswindows: + # subprocess._active is not used on Windows and is set to None. + self.assertIsNone(subprocess._active) + else: + # check that p is in the active processes list + self.assertIn(ident, [id(o) for o in subprocess._active]) def test_leak_fast_process_del_killed(self): # Issue #12650: on Unix, if Popen.__del__() was called before the @@ -2702,8 +2735,12 @@ def test_leak_fast_process_del_killed(self): p = None os.kill(pid, signal.SIGKILL) - # check that p is in the active processes list - self.assertIn(ident, [id(o) for o in subprocess._active]) + if mswindows: + # subprocess._active is not used on Windows and is set to None. + self.assertIsNone(subprocess._active) + else: + # check that p is in the active processes list + self.assertIn(ident, [id(o) for o in subprocess._active]) # let some time for the process to exit, and create a new Popen: this # should trigger the wait() of p @@ -2715,7 +2752,11 @@ def test_leak_fast_process_del_killed(self): pass # p should have been wait()ed on, and removed from the _active list self.assertRaises(OSError, os.waitpid, pid, 0) - self.assertNotIn(ident, [id(o) for o in subprocess._active]) + if mswindows: + # subprocess._active is not used on Windows and is set to None. + self.assertIsNone(subprocess._active) + else: + self.assertNotIn(ident, [id(o) for o in subprocess._active]) def test_close_fds_after_preexec(self): fd_status = support.findfile("fd_status.py", subdir="subprocessdata") @@ -2807,7 +2848,7 @@ def __int__(self): def test_communicate_BrokenPipeError_stdin_close(self): # By not setting stdout or stderr or a timeout we force the fast path # that just calls _stdin_write() internally due to our mock. - proc = subprocess.Popen([sys.executable, '-c', 'pass']) + proc = subprocess.Popen(ZERO_RETURN_CMD) with proc, mock.patch.object(proc, 'stdin') as mock_proc_stdin: mock_proc_stdin.close.side_effect = BrokenPipeError proc.communicate() # Should swallow BrokenPipeError from close. @@ -2816,7 +2857,7 @@ def test_communicate_BrokenPipeError_stdin_close(self): def test_communicate_BrokenPipeError_stdin_write(self): # By not setting stdout or stderr or a timeout we force the fast path # that just calls _stdin_write() internally due to our mock. - proc = subprocess.Popen([sys.executable, '-c', 'pass']) + proc = subprocess.Popen(ZERO_RETURN_CMD) with proc, mock.patch.object(proc, 'stdin') as mock_proc_stdin: mock_proc_stdin.write.side_effect = BrokenPipeError proc.communicate(b'stuff') # Should swallow the BrokenPipeError. @@ -2855,7 +2896,7 @@ def test_communicate_BrokenPipeError_stdin_close_with_timeout(self): 'need _testcapi.W_STOPCODE') def test_stopped(self): """Test wait() behavior when waitpid returns WIFSTOPPED; issue29335.""" - args = [sys.executable, '-c', 'pass'] + args = ZERO_RETURN_CMD proc = subprocess.Popen(args) # Wait until the real process completes to avoid zombie process @@ -2885,7 +2926,7 @@ def test_startupinfo(self): # Since Python is a console process, it won't be affected # by wShowWindow, but the argument should be silently # ignored - subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"], + subprocess.call(ZERO_RETURN_CMD, startupinfo=startupinfo) def test_startupinfo_keywords(self): @@ -2901,7 +2942,7 @@ def test_startupinfo_keywords(self): # Since Python is a console process, it won't be affected # by wShowWindow, but the argument should be silently # ignored - subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"], + subprocess.call(ZERO_RETURN_CMD, startupinfo=startupinfo) def test_startupinfo_copy(self): @@ -2913,7 +2954,7 @@ def test_startupinfo_copy(self): # Call Popen() twice with the same startupinfo object to make sure # that it's not modified for _ in range(2): - cmd = [sys.executable, "-c", "pass"] + cmd = ZERO_RETURN_CMD with open(os.devnull, 'w') as null: proc = subprocess.Popen(cmd, stdout=null, @@ -2953,7 +2994,7 @@ def test_issue31471(self): class BadEnv(dict): keys = None with self.assertRaises(TypeError): - subprocess.Popen([sys.executable, "-c", "pass"], env=BadEnv()) + subprocess.Popen(ZERO_RETURN_CMD, env=BadEnv()) def test_close_fds(self): # close file descriptors @@ -3014,13 +3055,13 @@ def test_close_fds_with_stdio(self): def test_empty_attribute_list(self): startupinfo = subprocess.STARTUPINFO() startupinfo.lpAttributeList = {} - subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"], + subprocess.call(ZERO_RETURN_CMD, startupinfo=startupinfo) def test_empty_handle_list(self): startupinfo = subprocess.STARTUPINFO() startupinfo.lpAttributeList = {"handle_list": []} - subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"], + subprocess.call(ZERO_RETURN_CMD, startupinfo=startupinfo) def test_shell_sequence(self): @@ -3319,7 +3360,7 @@ def test_invalid_args(self): def test_broken_pipe_cleanup(self): """Broken pipe error should not prevent wait() (Issue 21619)""" - proc = subprocess.Popen([sys.executable, '-c', 'pass'], + proc = subprocess.Popen(ZERO_RETURN_CMD, stdin=subprocess.PIPE, bufsize=support.PIPE_MAX_SIZE*2) proc = proc.__enter__() diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 8451c072f64209..3829746f1799a2 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -697,18 +697,47 @@ def test_break_outside_loop(self): self._check_error("break", "outside loop") def test_yield_outside_function(self): - self._check_error("if 0: yield", "outside function") - self._check_error("class C:\n if 0: yield", "outside function") + self._check_error("if 0: yield", "outside function") + self._check_error("if 0: yield\nelse: x=1", "outside function") + self._check_error("if 1: pass\nelse: yield", "outside function") + self._check_error("while 0: yield", "outside function") + self._check_error("while 0: yield\nelse: x=1", "outside function") + self._check_error("class C:\n if 0: yield", "outside function") + self._check_error("class C:\n if 1: pass\n else: yield", + "outside function") + self._check_error("class C:\n while 0: yield", "outside function") + self._check_error("class C:\n while 0: yield\n else: x = 1", + "outside function") def test_return_outside_function(self): - self._check_error("if 0: return", "outside function") - self._check_error("class C:\n if 0: return", "outside function") + self._check_error("if 0: return", "outside function") + self._check_error("if 0: return\nelse: x=1", "outside function") + self._check_error("if 1: pass\nelse: return", "outside function") + self._check_error("while 0: return", "outside function") + self._check_error("class C:\n if 0: return", "outside function") + self._check_error("class C:\n while 0: return", "outside function") + self._check_error("class C:\n while 0: return\n else: x=1", + "outside function") + self._check_error("class C:\n if 0: return\n else: x= 1", + "outside function") + self._check_error("class C:\n if 1: pass\n else: return", + "outside function") def test_break_outside_loop(self): - self._check_error("if 0: break", "outside loop") + self._check_error("if 0: break", "outside loop") + self._check_error("if 0: break\nelse: x=1", "outside loop") + self._check_error("if 1: pass\nelse: break", "outside loop") + self._check_error("class C:\n if 0: break", "outside loop") + self._check_error("class C:\n if 1: pass\n else: break", + "outside loop") def test_continue_outside_loop(self): - self._check_error("if 0: continue", "not properly in loop") + self._check_error("if 0: continue", "not properly in loop") + self._check_error("if 0: continue\nelse: x=1", "not properly in loop") + self._check_error("if 1: pass\nelse: continue", "not properly in loop") + self._check_error("class C:\n if 0: continue", "not properly in loop") + self._check_error("class C:\n if 1: pass\n else: continue", + "not properly in loop") def test_unexpected_indent(self): self._check_error("foo()\n bar()\n", "unexpected indent", diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 49f2722d95140e..af0e54bd0e2386 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1,81 +1,103 @@ -import unittest, test.support +from test import support from test.support.script_helper import assert_python_ok, assert_python_failure -import sys, io, os +import builtins +import codecs +import gc +import locale +import operator +import os import struct import subprocess +import sys +import sysconfig +import test.support import textwrap +import unittest import warnings -import operator -import codecs -import gc -import sysconfig -import locale + # count the number of test runs, used to create unique # strings to intern in test_intern() -numruns = 0 +INTERN_NUMRUNS = 0 -class SysModuleTest(unittest.TestCase): +class DisplayHookTest(unittest.TestCase): - def setUp(self): - self.orig_stdout = sys.stdout - self.orig_stderr = sys.stderr - self.orig_displayhook = sys.displayhook + def test_original_displayhook(self): + dh = sys.__displayhook__ - def tearDown(self): - sys.stdout = self.orig_stdout - sys.stderr = self.orig_stderr - sys.displayhook = self.orig_displayhook - test.support.reap_children() + with support.captured_stdout() as out: + dh(42) - def test_original_displayhook(self): - import builtins - out = io.StringIO() - sys.stdout = out + self.assertEqual(out.getvalue(), "42\n") + self.assertEqual(builtins._, 42) - dh = sys.__displayhook__ + del builtins._ - self.assertRaises(TypeError, dh) - if hasattr(builtins, "_"): - del builtins._ + with support.captured_stdout() as out: + dh(None) - dh(None) self.assertEqual(out.getvalue(), "") self.assertTrue(not hasattr(builtins, "_")) - dh(42) - self.assertEqual(out.getvalue(), "42\n") - self.assertEqual(builtins._, 42) - del sys.stdout - self.assertRaises(RuntimeError, dh, 42) + # sys.displayhook() requires arguments + self.assertRaises(TypeError, dh) + + stdout = sys.stdout + try: + del sys.stdout + self.assertRaises(RuntimeError, dh, 42) + finally: + sys.stdout = stdout def test_lost_displayhook(self): - del sys.displayhook - code = compile("42", "", "single") - self.assertRaises(RuntimeError, eval, code) + displayhook = sys.displayhook + try: + del sys.displayhook + code = compile("42", "", "single") + self.assertRaises(RuntimeError, eval, code) + finally: + sys.displayhook = displayhook def test_custom_displayhook(self): def baddisplayhook(obj): raise ValueError - sys.displayhook = baddisplayhook - code = compile("42", "", "single") - self.assertRaises(ValueError, eval, code) - def test_original_excepthook(self): - err = io.StringIO() - sys.stderr = err + with support.swap_attr(sys, 'displayhook', baddisplayhook): + code = compile("42", "", "single") + self.assertRaises(ValueError, eval, code) + - eh = sys.__excepthook__ +class ExceptHookTest(unittest.TestCase): - self.assertRaises(TypeError, eh) + def test_original_excepthook(self): try: raise ValueError(42) except ValueError as exc: - eh(*sys.exc_info()) + with support.captured_stderr() as err: + sys.__excepthook__(*sys.exc_info()) self.assertTrue(err.getvalue().endswith("ValueError: 42\n")) + self.assertRaises(TypeError, sys.__excepthook__) + + def test_excepthook_bytes_filename(self): + # bpo-37467: sys.excepthook() must not crash if a filename + # is a bytes string + with warnings.catch_warnings(): + warnings.simplefilter('ignore', BytesWarning) + + try: + raise SyntaxError("msg", (b"bytes_filename", 123, 0, "text")) + except SyntaxError as exc: + with support.captured_stderr() as err: + sys.__excepthook__(*sys.exc_info()) + + err = err.getvalue() + self.assertIn(""" File "b'bytes_filename'", line 123\n""", err) + self.assertIn(""" text\n""", err) + self.assertTrue(err.endswith("SyntaxError: msg\n")) + def test_excepthook(self): with test.support.captured_output("stderr") as stderr: sys.excepthook(1, '1', 1) @@ -85,6 +107,12 @@ def test_excepthook(self): # FIXME: testing the code for a lost or replaced excepthook in # Python/pythonrun.c::PyErr_PrintEx() is tricky. + +class SysModuleTest(unittest.TestCase): + + def tearDown(self): + test.support.reap_children() + def test_exit(self): # call with two arguments self.assertRaises(TypeError, sys.exit, 42, 42) @@ -501,10 +529,10 @@ def test_43581(self): self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding) def test_intern(self): - global numruns - numruns += 1 + global INTERN_NUMRUNS + INTERN_NUMRUNS += 1 self.assertRaises(TypeError, sys.intern) - s = "never interned before" + str(numruns) + s = "never interned before" + str(INTERN_NUMRUNS) self.assertTrue(sys.intern(s) is s) s2 = s.swapcase().swapcase() self.assertTrue(sys.intern(s2) is s) @@ -1275,7 +1303,7 @@ def delx(self): del self.__x check((1,2,3), vsize('') + 3*self.P) # type # static type: PyTypeObject - fmt = 'P2nPI13Pl4Pn9Pn11PIPP' + fmt = 'P2nPI13Pl4Pn9Pn11PIPPP' if hasattr(sys, 'getcounts'): fmt += '3n2P' s = vsize(fmt) diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 112ea877205abc..fdd789475d04dc 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -53,22 +53,52 @@ def basic(): # following that clause? -# The entire "while 0:" statement is optimized away. No code -# exists for it, so the line numbers skip directly from "del x" -# to "x = 1". -def arigo_example(): +# Some constructs like "while 0:", "if 0:" or "if 1:...else:..." are optimized +# away. No code # exists for them, so the line numbers skip directly from +# "del x" to "x = 1". +def arigo_example0(): x = 1 del x while 0: pass x = 1 -arigo_example.events = [(0, 'call'), +arigo_example0.events = [(0, 'call'), (1, 'line'), (2, 'line'), (5, 'line'), (5, 'return')] +def arigo_example1(): + x = 1 + del x + if 0: + pass + x = 1 + +arigo_example1.events = [(0, 'call'), + (1, 'line'), + (2, 'line'), + (5, 'line'), + (5, 'return')] + +def arigo_example2(): + x = 1 + del x + if 1: + x = 1 + else: + pass + return None + +arigo_example2.events = [(0, 'call'), + (1, 'line'), + (2, 'line'), + (4, 'line'), + (7, 'line'), + (7, 'return')] + + # check that lines consisting of just one instruction get traced: def one_instr_line(): x = 1 @@ -349,8 +379,12 @@ def fn(*args): def test_01_basic(self): self.run_test(basic) - def test_02_arigo(self): - self.run_test(arigo_example) + def test_02_arigo0(self): + self.run_test(arigo_example0) + def test_02_arigo1(self): + self.run_test(arigo_example1) + def test_02_arigo2(self): + self.run_test(arigo_example2) def test_03_one_instr(self): self.run_test(one_instr_line) def test_04_no_pop_blocks(self): diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 1b1929885edd6b..44e44bf5ea995f 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -6,7 +6,8 @@ from copy import copy from test.support import (import_module, TESTFN, unlink, check_warnings, - captured_stdout, skip_unless_symlink, change_cwd) + captured_stdout, skip_unless_symlink, change_cwd, + PythonSymlink) import sysconfig from sysconfig import (get_paths, get_platform, get_config_vars, @@ -232,39 +233,10 @@ def test_get_scheme_names(self): self.assertEqual(get_scheme_names(), wanted) @skip_unless_symlink - def test_symlink(self): - # On Windows, the EXE needs to know where pythonXY.dll is at so we have - # to add the directory to the path. - env = None - if sys.platform == "win32": - env = {k.upper(): os.environ[k] for k in os.environ} - env["PATH"] = "{};{}".format( - os.path.dirname(sys.executable), env.get("PATH", "")) - # Requires PYTHONHOME as well since we locate stdlib from the - # EXE path and not the DLL path (which should be fixed) - env["PYTHONHOME"] = os.path.dirname(sys.executable) - if sysconfig.is_python_build(True): - env["PYTHONPATH"] = os.path.dirname(os.__file__) - - # Issue 7880 - def get(python, env=None): - cmd = [python, '-c', - 'import sysconfig; print(sysconfig.get_platform())'] - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, env=env) - out, err = p.communicate() - if p.returncode: - print((out, err)) - self.fail('Non-zero return code {0} (0x{0:08X})' - .format(p.returncode)) - return out, err - real = os.path.realpath(sys.executable) - link = os.path.abspath(TESTFN) - os.symlink(real, link) - try: - self.assertEqual(get(real), get(link, env)) - finally: - unlink(link) + def test_symlink(self): # Issue 7880 + with PythonSymlink() as py: + cmd = "-c", "import sysconfig; print(sysconfig.get_platform())" + self.assertEqual(py.call_real(*cmd), py.call_link(*cmd)) def test_user_similar(self): # Issue #8759: make sure the posix scheme for the users diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py index 81549d14ae2b79..95840d6ac0c5f4 100644 --- a/Lib/test/test_tabnanny.py +++ b/Lib/test/test_tabnanny.py @@ -7,7 +7,6 @@ from unittest import mock import errno import os -import sys import tabnanny import tokenize import tempfile diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 7e32cbccd6c56d..15324a4e48819e 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -1,7 +1,7 @@ import sys import os import io -from hashlib import md5 +from hashlib import sha256 from contextlib import contextmanager from random import Random import pathlib @@ -11,7 +11,7 @@ import tarfile from test import support -from test.support import script_helper +from test.support import script_helper, requires_hashdigest # Check for our compression modules. try: @@ -27,8 +27,8 @@ except ImportError: lzma = None -def md5sum(data): - return md5(data).hexdigest() +def sha256sum(data): + return sha256(data).hexdigest() TEMPDIR = os.path.abspath(support.TESTFN) + "-tardir" tarextdir = TEMPDIR + '-extract-test' @@ -39,8 +39,12 @@ def md5sum(data): tmpname = os.path.join(TEMPDIR, "tmp.tar") dotlessname = os.path.join(TEMPDIR, "testtar") -md5_regtype = "65f477c818ad9e15f7feab0c6d37742f" -md5_sparse = "a54fbc4ca4f4399a90e1b27164012fc6" +sha256_regtype = ( + "e09e4bc8b3c9d9177e77256353b36c159f5f040531bbd4b024a8f9b9196c71ce" +) +sha256_sparse = ( + "4f05a776071146756345ceee937b33fc5644f5a96b9780d1c7d6a32cdf164d7b" +) class TarTest: @@ -95,7 +99,7 @@ def test_fileobj_regular_file(self): data = fobj.read() self.assertEqual(len(data), tarinfo.size, "regular file extraction failed") - self.assertEqual(md5sum(data), md5_regtype, + self.assertEqual(sha256sum(data), sha256_regtype, "regular file extraction failed") def test_fileobj_readlines(self): @@ -178,7 +182,7 @@ def test_fileobj_text(self): with self.tar.extractfile("ustar/regtype") as fobj: fobj = io.TextIOWrapper(fobj) data = fobj.read().encode("iso8859-1") - self.assertEqual(md5sum(data), md5_regtype) + self.assertEqual(sha256sum(data), sha256_regtype) try: fobj.seek(100) except AttributeError: @@ -543,13 +547,13 @@ def test_extract_hardlink(self): self.addCleanup(support.unlink, os.path.join(TEMPDIR, "ustar/lnktype")) with open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb") as f: data = f.read() - self.assertEqual(md5sum(data), md5_regtype) + self.assertEqual(sha256sum(data), sha256_regtype) tar.extract("ustar/symtype", TEMPDIR) self.addCleanup(support.unlink, os.path.join(TEMPDIR, "ustar/symtype")) with open(os.path.join(TEMPDIR, "ustar/symtype"), "rb") as f: data = f.read() - self.assertEqual(md5sum(data), md5_regtype) + self.assertEqual(sha256sum(data), sha256_regtype) def test_extractall(self): # Test if extractall() correctly restores directory permissions @@ -684,7 +688,7 @@ def test_fileobj_regular_file(self): data = fobj.read() self.assertEqual(len(data), tarinfo.size, "regular file extraction failed") - self.assertEqual(md5sum(data), md5_regtype, + self.assertEqual(sha256sum(data), sha256_regtype, "regular file extraction failed") def test_provoke_stream_error(self): @@ -796,8 +800,8 @@ class MemberReadTest(ReadTest, unittest.TestCase): def _test_member(self, tarinfo, chksum=None, **kwargs): if chksum is not None: with self.tar.extractfile(tarinfo) as f: - self.assertEqual(md5sum(f.read()), chksum, - "wrong md5sum for %s" % tarinfo.name) + self.assertEqual(sha256sum(f.read()), chksum, + "wrong sha256sum for %s" % tarinfo.name) kwargs["mtime"] = 0o7606136617 kwargs["uid"] = 1000 @@ -812,11 +816,11 @@ def _test_member(self, tarinfo, chksum=None, **kwargs): def test_find_regtype(self): tarinfo = self.tar.getmember("ustar/regtype") - self._test_member(tarinfo, size=7011, chksum=md5_regtype) + self._test_member(tarinfo, size=7011, chksum=sha256_regtype) def test_find_conttype(self): tarinfo = self.tar.getmember("ustar/conttype") - self._test_member(tarinfo, size=7011, chksum=md5_regtype) + self._test_member(tarinfo, size=7011, chksum=sha256_regtype) def test_find_dirtype(self): tarinfo = self.tar.getmember("ustar/dirtype") @@ -848,28 +852,28 @@ def test_find_fifotype(self): def test_find_sparse(self): tarinfo = self.tar.getmember("ustar/sparse") - self._test_member(tarinfo, size=86016, chksum=md5_sparse) + self._test_member(tarinfo, size=86016, chksum=sha256_sparse) def test_find_gnusparse(self): tarinfo = self.tar.getmember("gnu/sparse") - self._test_member(tarinfo, size=86016, chksum=md5_sparse) + self._test_member(tarinfo, size=86016, chksum=sha256_sparse) def test_find_gnusparse_00(self): tarinfo = self.tar.getmember("gnu/sparse-0.0") - self._test_member(tarinfo, size=86016, chksum=md5_sparse) + self._test_member(tarinfo, size=86016, chksum=sha256_sparse) def test_find_gnusparse_01(self): tarinfo = self.tar.getmember("gnu/sparse-0.1") - self._test_member(tarinfo, size=86016, chksum=md5_sparse) + self._test_member(tarinfo, size=86016, chksum=sha256_sparse) def test_find_gnusparse_10(self): tarinfo = self.tar.getmember("gnu/sparse-1.0") - self._test_member(tarinfo, size=86016, chksum=md5_sparse) + self._test_member(tarinfo, size=86016, chksum=sha256_sparse) def test_find_umlauts(self): tarinfo = self.tar.getmember("ustar/umlauts-" "\xc4\xd6\xdc\xe4\xf6\xfc\xdf") - self._test_member(tarinfo, size=7011, chksum=md5_regtype) + self._test_member(tarinfo, size=7011, chksum=sha256_regtype) def test_find_ustar_longname(self): name = "ustar/" + "12345/" * 39 + "1234567/longname" @@ -877,7 +881,7 @@ def test_find_ustar_longname(self): def test_find_regtype_oldv7(self): tarinfo = self.tar.getmember("misc/regtype-old-v7") - self._test_member(tarinfo, size=7011, chksum=md5_regtype) + self._test_member(tarinfo, size=7011, chksum=sha256_regtype) def test_find_pax_umlauts(self): self.tar.close() @@ -885,7 +889,7 @@ def test_find_pax_umlauts(self): encoding="iso8859-1") tarinfo = self.tar.getmember("pax/umlauts-" "\xc4\xd6\xdc\xe4\xf6\xfc\xdf") - self._test_member(tarinfo, size=7011, chksum=md5_regtype) + self._test_member(tarinfo, size=7011, chksum=sha256_regtype) class LongnameTest: @@ -947,8 +951,8 @@ def _test_sparse_file(self, name): filename = os.path.join(TEMPDIR, name) with open(filename, "rb") as fobj: data = fobj.read() - self.assertEqual(md5sum(data), md5_sparse, - "wrong md5sum for %s" % name) + self.assertEqual(sha256sum(data), sha256_sparse, + "wrong sha256sum for %s" % name) if self._fs_supports_holes(): s = os.stat(filename) @@ -2443,7 +2447,7 @@ def _test_link_extraction(self, name): self.tar.extract(name, TEMPDIR) with open(os.path.join(TEMPDIR, name), "rb") as f: data = f.read() - self.assertEqual(md5sum(data), md5_regtype) + self.assertEqual(sha256sum(data), sha256_regtype) # See issues #1578269, #8879, and #17689 for some history on these skips @unittest.skipIf(hasattr(os.path, "islink"), diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index 80f1668bcecab8..3183ea850f73b7 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -429,9 +429,12 @@ def passValue(value): self.assertEqual(passValue(False), False if self.wantobjects else '0') self.assertEqual(passValue('string'), 'string') self.assertEqual(passValue('string\u20ac'), 'string\u20ac') + self.assertEqual(passValue('string\U0001f4bb'), 'string\U0001f4bb') self.assertEqual(passValue('str\x00ing'), 'str\x00ing') self.assertEqual(passValue('str\x00ing\xbd'), 'str\x00ing\xbd') self.assertEqual(passValue('str\x00ing\u20ac'), 'str\x00ing\u20ac') + self.assertEqual(passValue('str\x00ing\U0001f4bb'), + 'str\x00ing\U0001f4bb') self.assertEqual(passValue(b'str\x00ing'), b'str\x00ing' if self.wantobjects else 'str\x00ing') self.assertEqual(passValue(b'str\xc0\x80ing'), @@ -490,6 +493,7 @@ def float_eq(actual, expected): check('string') check('string\xbd') check('string\u20ac') + check('string\U0001f4bb') check('') check(b'string', 'string') check(b'string\xe2\x82\xac', 'string\xe2\x82\xac') @@ -531,6 +535,7 @@ def test_splitlist(self): ('a\n b\t\r c\n ', ('a', 'b', 'c')), (b'a\n b\t\r c\n ', ('a', 'b', 'c')), ('a \u20ac', ('a', '\u20ac')), + ('a \U0001f4bb', ('a', '\U0001f4bb')), (b'a \xe2\x82\xac', ('a', '\u20ac')), (b'a\xc0\x80b c\xc0\x80d', ('a\x00b', 'c\x00d')), ('a {b c}', ('a', 'b c')), diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index bd4db839331b49..f995f6c9bfaf00 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -3,6 +3,7 @@ import errno import io import os +import pathlib import signal import sys import re @@ -56,6 +57,9 @@ def test_infer_return_type_multiples_and_none(self): with self.assertRaises(TypeError): tempfile._infer_return_type(b'', None, '') + def test_infer_return_type_pathlib(self): + self.assertIs(str, tempfile._infer_return_type(pathlib.Path('/'))) + # Common functionality. @@ -79,8 +83,13 @@ def nameCheck(self, name, dir, pre, suf): nsuf = nbase[len(nbase)-len(suf):] if dir is not None: - self.assertIs(type(name), str if type(dir) is str else bytes, - "unexpected return type") + self.assertIs( + type(name), + str + if type(dir) is str or isinstance(dir, os.PathLike) else + bytes, + "unexpected return type", + ) if pre is not None: self.assertIs(type(name), str if type(pre) is str else bytes, "unexpected return type") @@ -425,6 +434,7 @@ def test_choose_directory(self): dir = tempfile.mkdtemp() try: self.do_create(dir=dir).write(b"blat") + self.do_create(dir=pathlib.Path(dir)).write(b"blat") finally: os.rmdir(dir) @@ -659,6 +669,7 @@ def test_choose_directory(self): dir = tempfile.mkdtemp() try: self.do_create(dir=dir) + self.do_create(dir=pathlib.Path(dir)) finally: os.rmdir(dir) @@ -728,6 +739,7 @@ def test_choose_directory(self): dir = tempfile.mkdtemp() try: os.rmdir(self.do_create(dir=dir)) + os.rmdir(self.do_create(dir=pathlib.Path(dir))) finally: os.rmdir(dir) diff --git a/Lib/test/test_threaded_import.py b/Lib/test/test_threaded_import.py index 035344be4b8997..8607f363db21c0 100644 --- a/Lib/test/test_threaded_import.py +++ b/Lib/test/test_threaded_import.py @@ -15,7 +15,7 @@ import unittest from unittest import mock from test.support import ( - verbose, import_module, run_unittest, TESTFN, reap_threads, + verbose, run_unittest, TESTFN, reap_threads, forget, unlink, rmtree, start_threads) def task(N, done, done_tasks, errors): diff --git a/Lib/test/test_threadedtempfile.py b/Lib/test/test_threadedtempfile.py index f3d4ba36377dac..e1d7a10179cc11 100644 --- a/Lib/test/test_threadedtempfile.py +++ b/Lib/test/test_threadedtempfile.py @@ -13,19 +13,22 @@ provoking a 2.0 failure under Linux. """ -NUM_THREADS = 20 -FILES_PER_THREAD = 50 - import tempfile -from test.support import start_threads, import_module +from test.support import start_threads import unittest import io import threading from traceback import print_exc + +NUM_THREADS = 20 +FILES_PER_THREAD = 50 + + startEvent = threading.Event() + class TempFileGreedy(threading.Thread): error_count = 0 ok_count = 0 diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 6ac4ea9623de0d..ac4e7a7e0f53b3 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -583,6 +583,41 @@ def __del__(self): self.assertEqual(data.splitlines(), ["GC: True True True"] * 2) + def test_finalization_shutdown(self): + # bpo-36402: Py_Finalize() calls threading._shutdown() which must wait + # until Python thread states of all non-daemon threads get deleted. + # + # Test similar to SubinterpThreadingTests.test_threads_join_2(), but + # test the finalization of the main interpreter. + code = """if 1: + import os + import threading + import time + import random + + def random_sleep(): + seconds = random.random() * 0.010 + time.sleep(seconds) + + class Sleeper: + def __del__(self): + random_sleep() + + tls = threading.local() + + def f(): + # Sleep a bit so that the thread is still running when + # Py_Finalize() is called. + random_sleep() + tls.x = Sleeper() + random_sleep() + + threading.Thread(target=f).start() + random_sleep() + """ + rc, out, err = assert_python_ok("-c", code) + self.assertEqual(err, b"") + def test_tstate_lock(self): # Test an implementation detail of Thread objects. started = _thread.allocate_lock() @@ -703,6 +738,30 @@ def callback(): finally: sys.settrace(old_trace) + @cpython_only + def test_shutdown_locks(self): + for daemon in (False, True): + with self.subTest(daemon=daemon): + event = threading.Event() + thread = threading.Thread(target=event.wait, daemon=daemon) + + # Thread.start() must add lock to _shutdown_locks, + # but only for non-daemon thread + thread.start() + tstate_lock = thread._tstate_lock + if not daemon: + self.assertIn(tstate_lock, threading._shutdown_locks) + else: + self.assertNotIn(tstate_lock, threading._shutdown_locks) + + # unblock the thread and join it + event.set() + thread.join() + + # Thread._stop() must remove tstate_lock from _shutdown_locks. + # Daemon threads must never add it to _shutdown_locks. + self.assertNotIn(tstate_lock, threading._shutdown_locks) + class ThreadJoinOnShutdown(BaseTestCase): @@ -878,15 +937,22 @@ def test_threads_join(self): self.addCleanup(os.close, w) code = r"""if 1: import os + import random import threading import time + def random_sleep(): + seconds = random.random() * 0.010 + time.sleep(seconds) + def f(): # Sleep a bit so that the thread is still running when # Py_EndInterpreter is called. - time.sleep(0.05) + random_sleep() os.write(%d, b"x") + threading.Thread(target=f).start() + random_sleep() """ % (w,) ret = test.support.run_in_subinterp(code) self.assertEqual(ret, 0) @@ -903,22 +969,29 @@ def test_threads_join_2(self): self.addCleanup(os.close, w) code = r"""if 1: import os + import random import threading import time + def random_sleep(): + seconds = random.random() * 0.010 + time.sleep(seconds) + class Sleeper: def __del__(self): - time.sleep(0.05) + random_sleep() tls = threading.local() def f(): # Sleep a bit so that the thread is still running when # Py_EndInterpreter is called. - time.sleep(0.05) + random_sleep() tls.x = Sleeper() os.write(%d, b"x") + threading.Thread(target=f).start() + random_sleep() """ % (w,) ret = test.support.run_in_subinterp(code) self.assertEqual(ret, 0) @@ -976,8 +1049,6 @@ def test_releasing_unacquired_lock(self): lock = threading.Lock() self.assertRaises(RuntimeError, lock.release) - @unittest.skipUnless(sys.platform == 'darwin' and test.support.python_is_optimized(), - 'test macosx problem') def test_recursion_limit(self): # Issue 9670 # test that excessive recursion within a non-main thread causes diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index f790d43b6f4746..8d8d31e7825e68 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -14,6 +14,7 @@ except ImportError: _testcapi = None +from test.support import skip_if_buggy_ucrt_strfptime # Max year is only limited by the size of C int. SIZEOF_INT = sysconfig.get_config_var('SIZEOF_INT') or 4 @@ -250,6 +251,7 @@ def test_default_values_for_zero(self): result = time.strftime("%Y %m %d %H %M %S %w %j", (2000,)+(0,)*8) self.assertEqual(expected, result) + @skip_if_buggy_ucrt_strfptime def test_strptime(self): # Should be able to go round-trip from strftime to strptime without # raising an exception. @@ -672,6 +674,7 @@ 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") def test_localtime_timezone(self): diff --git a/Lib/test/test_timeout.py b/Lib/test/test_timeout.py index b54fc826ae0aa7..b07c07cbfc4df6 100644 --- a/Lib/test/test_timeout.py +++ b/Lib/test/test_timeout.py @@ -150,6 +150,7 @@ def setUp(self): def tearDown(self): self.sock.close() + @unittest.skipIf(True, 'need to replace these hosts; see bpo-35518') def testConnectTimeout(self): # Testing connect timeout is tricky: we need to have IP connectivity # to a host that silently drops our packets. We can't simulate this diff --git a/Lib/test/test_tools/test_lll.py b/Lib/test/test_tools/test_lll.py index f3fbe961eee55a..b01e2188e1cf20 100644 --- a/Lib/test/test_tools/test_lll.py +++ b/Lib/test/test_tools/test_lll.py @@ -1,6 +1,7 @@ """Tests for the lll script in the Tools/script directory.""" import os +import sys import tempfile from test import support from test.test_tools import skip_if_missing, import_tool @@ -26,12 +27,13 @@ def test_lll_multiple_dirs(self): 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 -> {fn1}\n' + f'symlink -> {prefix}{fn1}\n' f'\n' f'{dir2}:\n' - f'symlink -> {fn2}\n' + f'symlink -> {prefix}{fn2}\n' ) diff --git a/Lib/test/test_tools/test_pathfix.py b/Lib/test/test_tools/test_pathfix.py new file mode 100644 index 00000000000000..ec361178e6d81f --- /dev/null +++ b/Lib/test/test_tools/test_pathfix.py @@ -0,0 +1,129 @@ +import os +import subprocess +import sys +import unittest +from test import support +from test.test_tools import import_tool, 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(support.unlink, support.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 = support.TESTFN + pathfix_arg = filename + + with open(filename, 'w', encoding='utf8') as f: + f.write(f'{shebang}\n' + 'print("Hello world")\n') + + proc = subprocess.run( + [sys.executable, self.script, + *pathfix_flags, '-n', pathfix_arg], + capture_output=True, text=1) + + if stdout == '' and proc.returncode == 0: + stdout = f'{filename}: updating\n' + self.assertEqual(proc.returncode, exitcode, proc) + self.assertEqual(proc.stdout, stdout, proc) + self.assertEqual(proc.stderr, stderr, 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 = support.TESTFN + '.d' + self.addCleanup(support.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_tracemalloc.py b/Lib/test/test_tracemalloc.py index c3866483b8aa3b..4b9bf4ed5da1dc 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -885,7 +885,7 @@ def check_env_var_invalid(self, nframe): return if b'PYTHONTRACEMALLOC: invalid number of frames' in stderr: return - self.fail(f"unexpeced output: {stderr!a}") + self.fail(f"unexpected output: {stderr!a}") def test_env_var_invalid(self): @@ -914,7 +914,7 @@ def check_sys_xoptions_invalid(self, nframe): return if b'-X tracemalloc=NFRAME: invalid number of frames' in stderr: return - self.fail(f"unexpeced output: {stderr!a}") + self.fail(f"unexpected output: {stderr!a}") def test_sys_xoptions_invalid(self): for nframe in INVALID_NFRAME: diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index 55b54e7f203edc..43be54efdbd974 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -228,8 +228,9 @@ def parse(self, source, feature_version=highest): feature_version=feature_version) def parse_all(self, source, minver=lowest, maxver=highest, expected_regex=""): - for feature_version in range(self.lowest, self.highest + 1): - if minver <= feature_version <= maxver: + for version in range(self.lowest, self.highest + 1): + feature_version = (3, version) + if minver <= version <= maxver: try: yield self.parse(source, feature_version) except SyntaxError as err: diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index a65d639fe9e112..104b7c035ca6eb 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -3,7 +3,7 @@ import pickle import re import sys -from unittest import TestCase, main, skipUnless, SkipTest, expectedFailure +from unittest import TestCase, main, skipUnless, SkipTest, skip from copy import copy, deepcopy from typing import Any, NoReturn @@ -961,6 +961,23 @@ def __init__(self, x): self.assertIsInstance(C(1), P) self.assertIsInstance(C(1), PG) + def test_protocol_checks_after_subscript(self): + class P(Protocol[T]): pass + class C(P[T]): pass + class Other1: pass + class Other2: pass + CA = C[Any] + + self.assertNotIsInstance(Other1(), C) + self.assertNotIsSubclass(Other2, C) + + class D1(C[Any]): pass + class D2(C[Any]): pass + CI = C[int] + + self.assertIsInstance(D1(), C) + self.assertIsSubclass(D2, C) + def test_protocols_support_register(self): @runtime_checkable class P(Protocol): @@ -1364,6 +1381,14 @@ def close(self): self.assertIsSubclass(B, Custom) self.assertNotIsSubclass(A, Custom) + def test_builtin_protocol_whitelist(self): + with self.assertRaises(TypeError): + class CustomProtocol(TestCase, Protocol): + pass + + class CustomContextManager(typing.ContextManager, Protocol): + pass + class GenericTests(BaseTestCase): def test_basics(self): @@ -2336,6 +2361,65 @@ def test_forward_equality(self): self.assertEqual(fr, typing.ForwardRef('int')) self.assertNotEqual(List['int'], List[int]) + def test_forward_equality_gth(self): + c1 = typing.ForwardRef('C') + c1_gth = typing.ForwardRef('C') + c2 = typing.ForwardRef('C') + c2_gth = typing.ForwardRef('C') + + class C: + pass + def foo(a: c1_gth, b: c2_gth): + pass + + self.assertEqual(get_type_hints(foo, globals(), locals()), {'a': C, 'b': C}) + self.assertEqual(c1, c2) + self.assertEqual(c1, c1_gth) + self.assertEqual(c1_gth, c2_gth) + self.assertEqual(List[c1], List[c1_gth]) + self.assertNotEqual(List[c1], List[C]) + self.assertNotEqual(List[c1_gth], List[C]) + self.assertEqual(Union[c1, c1_gth], Union[c1]) + self.assertEqual(Union[c1, c1_gth, int], Union[c1, int]) + + def test_forward_equality_hash(self): + c1 = typing.ForwardRef('int') + c1_gth = typing.ForwardRef('int') + c2 = typing.ForwardRef('int') + c2_gth = typing.ForwardRef('int') + + def foo(a: c1_gth, b: c2_gth): + pass + get_type_hints(foo, globals(), locals()) + + self.assertEqual(hash(c1), hash(c2)) + self.assertEqual(hash(c1_gth), hash(c2_gth)) + self.assertEqual(hash(c1), hash(c1_gth)) + + def test_forward_equality_namespace(self): + class A: + pass + def namespace1(): + a = typing.ForwardRef('A') + def fun(x: a): + pass + get_type_hints(fun, globals(), locals()) + return a + + def namespace2(): + a = typing.ForwardRef('A') + + class A: + pass + def fun(x: a): + pass + + get_type_hints(fun, globals(), locals()) + return a + + self.assertEqual(namespace1(), namespace1()) + self.assertNotEqual(namespace1(), namespace2()) + def test_forward_repr(self): self.assertEqual(repr(List['int']), "typing.List[ForwardRef('int')]") @@ -2355,6 +2439,63 @@ def foo(a: Tuple['T']): self.assertEqual(get_type_hints(foo, globals(), locals()), {'a': Tuple[T]}) + def test_forward_recursion_actually(self): + def namespace1(): + a = typing.ForwardRef('A') + A = a + def fun(x: a): pass + + ret = get_type_hints(fun, globals(), locals()) + return a + + def namespace2(): + a = typing.ForwardRef('A') + A = a + def fun(x: a): pass + + ret = get_type_hints(fun, globals(), locals()) + return a + + def cmp(o1, o2): + return o1 == o2 + + r1 = namespace1() + r2 = namespace2() + self.assertIsNot(r1, r2) + self.assertRaises(RecursionError, cmp, r1, r2) + + def test_union_forward_recursion(self): + ValueList = List['Value'] + Value = Union[str, ValueList] + + class C: + foo: List[Value] + class D: + foo: Union[Value, ValueList] + class E: + foo: Union[List[Value], ValueList] + class F: + foo: Union[Value, List[Value], ValueList] + + self.assertEqual(get_type_hints(C, globals(), locals()), get_type_hints(C, globals(), locals())) + self.assertEqual(get_type_hints(C, globals(), locals()), + {'foo': List[Union[str, List[Union[str, List['Value']]]]]}) + self.assertEqual(get_type_hints(D, globals(), locals()), + {'foo': Union[str, List[Union[str, List['Value']]]]}) + self.assertEqual(get_type_hints(E, globals(), locals()), + {'foo': Union[ + List[Union[str, List[Union[str, List['Value']]]]], + List[Union[str, List['Value']]] + ] + }) + self.assertEqual(get_type_hints(F, globals(), locals()), + {'foo': Union[ + str, + List[Union[str, List['Value']]], + List[Union[str, List[Union[str, List['Value']]]]] + ] + }) + def test_callable_forward(self): def foo(a: Callable[['T'], 'T']): @@ -2654,7 +2795,7 @@ def test_get_type_hints_modules(self): self.assertEqual(gth(ann_module2), {}) self.assertEqual(gth(ann_module3), {}) - @expectedFailure + @skip("known bug") def test_get_type_hints_modules_forwardref(self): # FIXME: This currently exposes a bug in typing. Cached forward references # don't account for the case where there are multiple types of the same @@ -3327,6 +3468,9 @@ class D(UserName): class NamedTupleTests(BaseTestCase): + class NestedEmployee(NamedTuple): + name: str + cool: int def test_basics(self): Emp = NamedTuple('Emp', [('name', str), ('id', int)]) @@ -3422,14 +3566,55 @@ def test_namedtuple_keyword_usage(self): with self.assertRaises(TypeError): NamedTuple('Name', x=1, y='a') - def test_pickle(self): + def test_namedtuple_special_keyword_names(self): + NT = NamedTuple("NT", cls=type, self=object, typename=str, fields=list) + self.assertEqual(NT.__name__, 'NT') + self.assertEqual(NT._fields, ('cls', 'self', 'typename', 'fields')) + a = NT(cls=str, self=42, typename='foo', fields=[('bar', tuple)]) + self.assertEqual(a.cls, str) + self.assertEqual(a.self, 42) + self.assertEqual(a.typename, 'foo') + self.assertEqual(a.fields, [('bar', tuple)]) + + def test_namedtuple_errors(self): + with self.assertRaises(TypeError): + NamedTuple.__new__() + with self.assertRaises(TypeError): + NamedTuple() + with self.assertRaises(TypeError): + NamedTuple('Emp', [('name', str)], None) + with self.assertRaises(ValueError): + NamedTuple('Emp', [('_name', str)]) + + with self.assertWarns(DeprecationWarning): + Emp = NamedTuple(typename='Emp', name=str, id=int) + self.assertEqual(Emp.__name__, 'Emp') + self.assertEqual(Emp._fields, ('name', 'id')) + + with self.assertWarns(DeprecationWarning): + Emp = NamedTuple('Emp', fields=[('name', str), ('id', int)]) + self.assertEqual(Emp.__name__, 'Emp') + self.assertEqual(Emp._fields, ('name', 'id')) + + def test_copy_and_pickle(self): global Emp # pickle wants to reference the class by name - Emp = NamedTuple('Emp', [('name', str), ('id', int)]) - jane = Emp('jane', 37) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - z = pickle.dumps(jane, proto) - jane2 = pickle.loads(z) - self.assertEqual(jane2, jane) + Emp = NamedTuple('Emp', [('name', str), ('cool', int)]) + for cls in Emp, CoolEmployee, self.NestedEmployee: + with self.subTest(cls=cls): + jane = cls('jane', 37) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z = pickle.dumps(jane, proto) + jane2 = pickle.loads(z) + self.assertEqual(jane2, jane) + self.assertIsInstance(jane2, cls) + + jane2 = copy(jane) + self.assertEqual(jane2, jane) + self.assertIsInstance(jane2, cls) + + jane2 = deepcopy(jane) + self.assertEqual(jane2, jane) + self.assertIsInstance(jane2, cls) class TypedDictTests(BaseTestCase): @@ -3463,6 +3648,30 @@ def test_basics_keywords_syntax(self): self.assertEqual(Emp.__annotations__, {'name': str, 'id': int}) 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) + 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}) + self.assertEqual(a['cls'], str) + self.assertEqual(a['self'], 42) + self.assertEqual(a['typename'], 'foo') + self.assertEqual(a['_typename'], 53) + self.assertEqual(a['fields'], [('bar', tuple)]) + self.assertEqual(a['_fields'], {'baz', set}) + + def test_typeddict_create_errors(self): + with self.assertRaises(TypeError): + TypedDict.__new__() + with self.assertRaises(TypeError): + 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}) self.assertEqual(TypedDict.__module__, 'typing') diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 36b72e40c7e419..1d6aabdbbcc940 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -11,6 +11,7 @@ import operator import struct import sys +import unicodedata import unittest import warnings from test import support, string_tests @@ -615,11 +616,21 @@ def test_isspace(self): self.checkequalnofix(True, '\u2000', 'isspace') self.checkequalnofix(True, '\u200a', 'isspace') self.checkequalnofix(False, '\u2014', 'isspace') - # apparently there are no non-BMP spaces chars in Unicode 6 + # There are no non-BMP whitespace chars as of Unicode 12. for ch in ['\U00010401', '\U00010427', '\U00010429', '\U0001044E', '\U0001F40D', '\U0001F46F']: self.assertFalse(ch.isspace(), '{!a} is not space.'.format(ch)) + @support.requires_resource('cpu') + def test_isspace_invariant(self): + for codepoint in range(sys.maxunicode + 1): + char = chr(codepoint) + bidirectional = unicodedata.bidirectional(char) + category = unicodedata.category(char) + self.assertEqual(char.isspace(), + (bidirectional in ('WS', 'B', 'S') + or category == 'Zs')) + def test_isalnum(self): super().test_isalnum() for ch in ['\U00010401', '\U00010427', '\U00010429', '\U0001044E', diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index a52b6de547fbc9..07d717688b0c59 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -220,6 +220,8 @@ def test_issue29456(self): self.assertEqual(self.db.normalize('NFC', u11a7_str_a), u11a7_str_b) self.assertEqual(self.db.normalize('NFC', u11c3_str_a), u11c3_str_b) + # For tests of unicodedata.is_normalized / self.db.is_normalized , + # see test_normalization.py . def test_east_asian_width(self): eaw = self.db.east_asian_width diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index f9b2799d25bfd0..801f0fd647f4ab 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -56,7 +56,7 @@ def FancyURLopener(): return urllib.request.FancyURLopener() -def fakehttp(fakedata): +def fakehttp(fakedata, mock_close=False): class FakeSocket(io.BytesIO): io_refs = 1 @@ -90,15 +90,24 @@ class FakeHTTPConnection(http.client.HTTPConnection): def connect(self): self.sock = FakeSocket(self.fakedata) type(self).fakesock = self.sock + + if mock_close: + # bpo-36918: HTTPConnection destructor calls close() which calls + # flush(). Problem: flush() calls self.fp.flush() which raises + # "ValueError: I/O operation on closed file" which is logged as an + # "Exception ignored in". Override close() to silence this error. + def close(self): + pass FakeHTTPConnection.fakedata = fakedata return FakeHTTPConnection class FakeHTTPMixin(object): - def fakehttp(self, fakedata): + def fakehttp(self, fakedata, mock_close=False): + fake_http_class = fakehttp(fakedata, mock_close=mock_close) self._connection_class = http.client.HTTPConnection - http.client.HTTPConnection = fakehttp(fakedata) + http.client.HTTPConnection = fake_http_class def unfakehttp(self): http.client.HTTPConnection = self._connection_class @@ -400,7 +409,7 @@ def test_read_bogus(self): Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e Connection: close Content-Type: text/html; charset=iso-8859-1 -''') +''', mock_close=True) try: self.assertRaises(OSError, urlopen, "http://python.org/") finally: @@ -414,7 +423,7 @@ def test_invalid_redirect(self): Location: file://guidocomputer.athome.com:/python/license Connection: close Content-Type: text/html; charset=iso-8859-1 -''') +''', mock_close=True) try: msg = "Redirection to url 'file:" with self.assertRaisesRegex(urllib.error.HTTPError, msg): @@ -429,7 +438,7 @@ def test_redirect_limit_independent(self): self.fakehttp(b'''HTTP/1.1 302 Found Location: file://guidocomputer.athome.com:/python/license Connection: close -''') +''', mock_close=True) try: self.assertRaises(urllib.error.HTTPError, urlopen, "http://something") diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index c6d275e16b097f..61e3ecc612d6c9 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1340,21 +1340,22 @@ def http_open(self, req): self.assertTrue(request.startswith(expected), repr(request)) def test_proxy(self): - o = OpenerDirector() - ph = urllib.request.ProxyHandler(dict(http="proxy.example.com:3128")) - o.add_handler(ph) - meth_spec = [ - [("http_open", "return response")] - ] - handlers = add_ordered_mock_handlers(o, meth_spec) - - req = Request("http://acme.example.com/") - self.assertEqual(req.host, "acme.example.com") - o.open(req) - self.assertEqual(req.host, "proxy.example.com:3128") - - self.assertEqual([(handlers[0], "http_open")], - [tup[0:2] for tup in o.calls]) + u = "proxy.example.com:3128" + for d in dict(http=u), dict(HTTP=u): + o = OpenerDirector() + ph = urllib.request.ProxyHandler(d) + o.add_handler(ph) + meth_spec = [ + [("http_open", "return response")] + ] + handlers = add_ordered_mock_handlers(o, meth_spec) + + req = Request("http://acme.example.com/") + self.assertEqual(req.host, "acme.example.com") + o.open(req) + self.assertEqual(req.host, u) + self.assertEqual([(handlers[0], "http_open")], + [tup[0:2] for tup in o.calls]) def test_proxy_no_proxy(self): os.environ['no_proxy'] = 'python.org' diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py index 591b48d6d4d76b..1cb358f8ddc8df 100644 --- a/Lib/test/test_urllib2_localnet.py +++ b/Lib/test/test_urllib2_localnet.py @@ -322,6 +322,7 @@ class ProxyAuthTests(unittest.TestCase): PASSWD = "test123" REALM = "TestRealm" + @support.requires_hashdigest("md5") def setUp(self): super(ProxyAuthTests, self).setUp() # Ignore proxy bypass settings in the environment. diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 4ae6ed33858ce2..762500789f73ac 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -709,15 +709,17 @@ def test_withoutscheme(self): def test_portseparator(self): # Issue 754016 makes changes for port separator ':' from scheme separator - self.assertEqual(urllib.parse.urlparse("path:80"), - ('','','path:80','','','')) + self.assertEqual(urllib.parse.urlparse("http:80"), ('http','','80','','','')) + self.assertEqual(urllib.parse.urlparse("https:80"), ('https','','80','','','')) + self.assertEqual(urllib.parse.urlparse("path:80"), ('path','','80','','','')) self.assertEqual(urllib.parse.urlparse("http:"),('http','','','','','')) self.assertEqual(urllib.parse.urlparse("https:"),('https','','','','','')) self.assertEqual(urllib.parse.urlparse("http://www.python.org:80"), ('http','www.python.org:80','','','','')) # As usual, need to check bytes input as well - self.assertEqual(urllib.parse.urlparse(b"path:80"), - (b'',b'',b'path:80',b'',b'',b'')) + self.assertEqual(urllib.parse.urlparse(b"http:80"), (b'http',b'',b'80',b'',b'',b'')) + self.assertEqual(urllib.parse.urlparse(b"https:80"), (b'https',b'',b'80',b'',b'',b'')) + self.assertEqual(urllib.parse.urlparse(b"path:80"), (b'path',b'',b'80',b'',b'',b'')) self.assertEqual(urllib.parse.urlparse(b"http:"),(b'http',b'',b'',b'',b'',b'')) self.assertEqual(urllib.parse.urlparse(b"https:"),(b'https',b'',b'',b'',b'',b'')) self.assertEqual(urllib.parse.urlparse(b"http://www.python.org:80"), diff --git a/Lib/test/test_userstring.py b/Lib/test/test_userstring.py index 19b0acfc760fa4..4d1d8b6b6fe2d9 100644 --- a/Lib/test/test_userstring.py +++ b/Lib/test/test_userstring.py @@ -51,6 +51,20 @@ def __rmod__(self, other): str3 = ustr3('TEST') self.assertEqual(fmt2 % str3, 'value is TEST') + def test_encode_default_args(self): + self.checkequal(b'hello', 'hello', 'encode') + # Check that encoding defaults to utf-8 + self.checkequal(b'\xf0\xa3\x91\x96', '\U00023456', 'encode') + # Check that errors defaults to 'strict' + self.checkraises(UnicodeError, '\ud800', 'encode') + + def test_encode_explicit_none_args(self): + self.checkequal(b'hello', 'hello', 'encode', None, None) + # Check that encoding defaults to utf-8 + self.checkequal(b'\xf0\xa3\x91\x96', '\U00023456', 'encode', None, None) + # Check that errors defaults to 'strict' + self.checkraises(UnicodeError, '\ud800', 'encode', None, None) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index 992ef0cbf8048c..92642d239b92cd 100644 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -462,8 +462,7 @@ def test_uuid1_eui64(self): with unittest.mock.patch.multiple( self.uuid, _node=None, # Ignore any cached node value. - _NODE_GETTERS_WIN32=[too_large_getter], - _NODE_GETTERS_UNIX=[too_large_getter], + _GETTERS=[too_large_getter], ): node = self.uuid.getnode() self.assertTrue(0 < node < (1 << 48), '%012x' % node) @@ -673,7 +672,7 @@ class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase): class BaseTestInternals: - uuid = None + _uuid = py_uuid @unittest.skipUnless(os.name == 'posix', 'requires Posix') def test_find_mac(self): @@ -708,27 +707,32 @@ def check_node(self, node, requires=None): self.assertTrue(0 < node < (1 << 48), "%s is not an RFC 4122 node ID" % hex) - @unittest.skipUnless(os.name == 'posix', 'requires Posix') + @unittest.skipUnless(_uuid._ifconfig_getnode in _uuid._GETTERS, + "ifconfig is not used for introspection on this platform") def test_ifconfig_getnode(self): node = self.uuid._ifconfig_getnode() self.check_node(node, 'ifconfig') - @unittest.skipUnless(os.name == 'posix', 'requires Posix') + @unittest.skipUnless(_uuid._ip_getnode in _uuid._GETTERS, + "ip is not used for introspection on this platform") def test_ip_getnode(self): node = self.uuid._ip_getnode() self.check_node(node, 'ip') - @unittest.skipUnless(os.name == 'posix', 'requires Posix') + @unittest.skipUnless(_uuid._arp_getnode in _uuid._GETTERS, + "arp is not used for introspection on this platform") def test_arp_getnode(self): node = self.uuid._arp_getnode() self.check_node(node, 'arp') - @unittest.skipUnless(os.name == 'posix', 'requires Posix') + @unittest.skipUnless(_uuid._lanscan_getnode in _uuid._GETTERS, + "lanscan is not used for introspection on this platform") def test_lanscan_getnode(self): node = self.uuid._lanscan_getnode() self.check_node(node, 'lanscan') - @unittest.skipUnless(os.name == 'posix', 'requires Posix') + @unittest.skipUnless(_uuid._netstat_getnode in _uuid._GETTERS, + "netstat is not used for introspection on this platform") def test_netstat_getnode(self): node = self.uuid._netstat_getnode() self.check_node(node, 'netstat') diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 24d3a69b1878b5..ede65935b650bb 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -9,6 +9,7 @@ import os import os.path import re +import shutil import struct import subprocess import sys @@ -28,8 +29,8 @@ # Platforms that set sys._base_executable can create venvs from within # another venv, so no need to skip tests that require venv.create(). requireVenvCreate = unittest.skipUnless( - hasattr(sys, '_base_executable') - or sys.prefix == sys.base_prefix, + sys.prefix == sys.base_prefix + or sys._base_executable != sys.executable, 'cannot run venv.create from within a venv on this platform') def check_output(cmd, encoding=None): @@ -57,8 +58,14 @@ def setUp(self): self.bindir = 'bin' self.lib = ('lib', 'python%d.%d' % sys.version_info[:2]) self.include = 'include' - executable = getattr(sys, '_base_executable', sys.executable) + executable = sys._base_executable self.exe = os.path.split(executable)[-1] + if (sys.platform == 'win32' + and os.path.lexists(executable) + and not os.path.exists(executable)): + self.cannot_link_exe = True + else: + self.cannot_link_exe = False def tearDown(self): rmtree(self.env_dir) @@ -102,7 +109,7 @@ def test_defaults(self): else: self.assertFalse(os.path.exists(p)) data = self.get_text_file_contents('pyvenv.cfg') - executable = getattr(sys, '_base_executable', sys.executable) + executable = sys._base_executable path = os.path.dirname(executable) self.assertIn('home = %s' % path, data) fn = self.get_env_file(self.bindir, self.exe) @@ -136,10 +143,6 @@ def test_prefixes(self): """ Test that the prefix values are as expected. """ - #check our prefixes - self.assertEqual(sys.base_prefix, sys.prefix) - self.assertEqual(sys.base_exec_prefix, sys.exec_prefix) - # check a venv's prefixes rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir) @@ -147,9 +150,9 @@ def test_prefixes(self): cmd = [envpy, '-c', None] for prefix, expected in ( ('prefix', self.env_dir), - ('prefix', self.env_dir), - ('base_prefix', sys.prefix), - ('base_exec_prefix', sys.exec_prefix)): + ('exec_prefix', self.env_dir), + ('base_prefix', sys.base_prefix), + ('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()) @@ -261,7 +264,12 @@ def test_symlinking(self): # symlinked to 'python3.3' in the env, even when symlinking in # general isn't wanted. if usl: - self.assertTrue(os.path.islink(fn)) + if self.cannot_link_exe: + # Symlinking is skipped when our executable is already a + # special app symlink + self.assertFalse(os.path.islink(fn)) + else: + self.assertTrue(os.path.islink(fn)) # If a venv is created from a source build and that venv is used to # run the test, the pyvenv.cfg in the venv created in the test will @@ -331,6 +339,25 @@ def test_multiprocessing(self): 'pool.terminate()']) self.assertEqual(out.strip(), "python".encode()) + @unittest.skipIf(os.name == 'nt', 'not relevant on Windows') + def test_deactivate_with_strict_bash_opts(self): + bash = shutil.which("bash") + if bash is None: + self.skipTest("bash required for this test") + rmtree(self.env_dir) + builder = venv.EnvBuilder(clear=True) + builder.create(self.env_dir) + activate = os.path.join(self.env_dir, self.bindir, "activate") + test_script = os.path.join(self.env_dir, "test_strict.sh") + with open(test_script, "w") as f: + f.write("set -euo pipefail\n" + f"source {activate}\n" + "deactivate\n") + out, err = check_output([bash, test_script]) + self.assertEqual(out, "".encode()) + self.assertEqual(err, "".encode()) + + @requireVenvCreate class EnsurePipTest(BaseTest): """Test venv module installation of pip.""" @@ -365,11 +392,7 @@ def test_devnull(self): with open(os.devnull, "rb") as f: self.assertEqual(f.read(), b"") - # Issue #20541: os.path.exists('nul') is False on Windows - if os.devnull.lower() == 'nul': - self.assertFalse(os.path.exists(os.devnull)) - else: - self.assertTrue(os.path.exists(os.devnull)) + self.assertTrue(os.path.exists(os.devnull)) def do_test_with_pip(self, system_site_packages): rmtree(self.env_dir) @@ -444,8 +467,9 @@ def do_test_with_pip(self, system_site_packages): # Please check the permissions and owner of that directory. If # executing pip with sudo, you may want sudo's -H flag." # where $HOME is replaced by the HOME environment variable. - err = re.sub("^The directory .* or its parent directory is not owned " - "by the current user .*$", "", err, flags=re.MULTILINE) + err = re.sub("^(WARNING: )?The directory .* or its parent directory " + "is not owned by the current user .*$", "", + err, flags=re.MULTILINE) self.assertEqual(err.rstrip(), "") # Being fairly specific regarding the expected behaviour for the # initial bundling phase in Python 3.4. If the output changes in diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index 86c2f226ebcf1f..fc3f8f6fe7f0c2 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -714,7 +714,7 @@ def test_showwarning_not_callable(self): self.assertRaises(TypeError, self.module.warn, "Warning!") def test_show_warning_output(self): - # With showarning() missing, make sure that output is okay. + # With showwarning() missing, make sure that output is okay. text = 'test show_warning' with original_warnings.catch_warnings(module=self.module): self.module.filterwarnings("always", category=UserWarning) diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 6f15c03ac5292f..2dbf3f452c10e6 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -391,6 +391,26 @@ class List(list): pass lyst = List() self.assertEqual(bool(weakref.proxy(lyst)), bool(lyst)) + def test_proxy_iter(self): + # Test fails with a debug build of the interpreter + # (see bpo-38395). + + obj = None + + class MyObj: + def __iter__(self): + nonlocal obj + del obj + return NotImplemented + + obj = MyObj() + p = weakref.proxy(obj) + with self.assertRaises(TypeError): + # "blech" in p calls MyObj.__iter__ through the proxy, + # without keeping a reference to the real object, so it + # can be killed in the middle of the call + "blech" in p + def test_getweakrefcount(self): o = C() ref1 = weakref.ref(o) @@ -1785,6 +1805,11 @@ def test_threaded_weak_value_dict_deepcopy(self): # copying should not result in a crash. self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, True) + @support.cpython_only + def test_remove_closure(self): + d = weakref.WeakValueDictionary() + self.assertIsNone(d._remove.__closure__) + from test import mapping_tests diff --git a/Lib/test/test_winconsoleio.py b/Lib/test/test_winconsoleio.py index a78fa4d7d919ff..9a61e48881d903 100644 --- a/Lib/test/test_winconsoleio.py +++ b/Lib/test/test_winconsoleio.py @@ -25,14 +25,12 @@ def test_open_fd(self): self.assertRaisesRegex(ValueError, "negative file descriptor", ConIO, -1) - fd, _ = tempfile.mkstemp() - try: + with tempfile.TemporaryFile() as tmpfile: + fd = tmpfile.fileno() # Windows 10: "Cannot open non-console file" # Earlier: "Cannot open console output buffer for reading" self.assertRaisesRegex(ValueError, "Cannot open (console|non-console file)", ConIO, fd) - finally: - os.close(fd) try: f = ConIO(0) diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index dc2b46e42521f3..5c25ec8f7ec674 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -41,6 +41,7 @@ ("String Val", "A string value", REG_SZ), ("StringExpand", "The path is %path%", REG_EXPAND_SZ), ("Multi-string", ["Lots", "of", "string", "values"], REG_MULTI_SZ), + ("Multi-nul", ["", "", "", ""], REG_MULTI_SZ), ("Raw Data", b"binary\x00data", REG_BINARY), ("Big String", "x"*(2**14-1), REG_SZ), ("Big Binary", b"x"*(2**14), REG_BINARY), @@ -229,7 +230,7 @@ def test_connect_registry_to_local_machine_works(self): h.Close() self.assertEqual(h.handle, 0) - def test_inexistant_remote_registry(self): + def test_nonexistent_remote_registry(self): connect = lambda: ConnectRegistry("abcdefghijkl", HKEY_CURRENT_USER) self.assertRaises(OSError, connect) diff --git a/Lib/test/test_wsgiref.py b/Lib/test/test_wsgiref.py index 42432bfbd260e7..6af45145a79279 100644 --- a/Lib/test/test_wsgiref.py +++ b/Lib/test/test_wsgiref.py @@ -548,32 +548,62 @@ def handle_error(self): class HandlerTests(TestCase): - - def checkEnvironAttrs(self, handler): - env = handler.environ - for attr in [ - 'version','multithread','multiprocess','run_once','file_wrapper' - ]: - if attr=='file_wrapper' and handler.wsgi_file_wrapper is None: - continue - self.assertEqual(getattr(handler,'wsgi_'+attr),env['wsgi.'+attr]) - - def checkOSEnviron(self,handler): - empty = {}; setup_testing_defaults(empty) - env = handler.environ - from os import environ - for k,v in environ.items(): - if k not in empty: - self.assertEqual(env[k],v) - for k,v in empty.items(): - self.assertIn(k, env) + # testEnviron() can produce long error message + maxDiff = 80 * 50 def testEnviron(self): - h = TestHandler(X="Y") - h.setup_environ() - self.checkEnvironAttrs(h) - self.checkOSEnviron(h) - self.assertEqual(h.environ["X"],"Y") + os_environ = { + # very basic environment + 'HOME': '/my/home', + 'PATH': '/my/path', + 'LANG': 'fr_FR.UTF-8', + + # set some WSGI variables + 'SCRIPT_NAME': 'test_script_name', + 'SERVER_NAME': 'test_server_name', + } + + with support.swap_attr(TestHandler, 'os_environ', os_environ): + # override X and HOME variables + handler = TestHandler(X="Y", HOME="/override/home") + handler.setup_environ() + + # Check that wsgi_xxx attributes are copied to wsgi.xxx variables + # of handler.environ + for attr in ('version', 'multithread', 'multiprocess', 'run_once', + 'file_wrapper'): + self.assertEqual(getattr(handler, 'wsgi_' + attr), + handler.environ['wsgi.' + attr]) + + # Test handler.environ as a dict + expected = {} + setup_testing_defaults(expected) + # Handler inherits os_environ variables which are not overriden + # by SimpleHandler.add_cgi_vars() (SimpleHandler.base_env) + for key, value in os_environ.items(): + if key not in expected: + expected[key] = value + expected.update({ + # X doesn't exist in os_environ + "X": "Y", + # HOME is overridden by TestHandler + 'HOME': "/override/home", + + # overridden by setup_testing_defaults() + "SCRIPT_NAME": "", + "SERVER_NAME": "127.0.0.1", + + # set by BaseHandler.setup_environ() + 'wsgi.input': handler.get_stdin(), + 'wsgi.errors': handler.get_stderr(), + 'wsgi.version': (1, 0), + 'wsgi.run_once': False, + 'wsgi.url_scheme': 'http', + 'wsgi.multithread': True, + 'wsgi.multiprocess': True, + 'wsgi.file_wrapper': util.FileWrapper, + }) + self.assertDictEqual(handler.environ, expected) def testCGIEnviron(self): h = BaseCGIHandler(None,None,None,{}) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 61737493a9047b..b2492cda848f9e 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -2954,6 +2954,66 @@ def test_treebuilder_pi(self): self.assertEqual(b.pi('target'), (len('target'), None)) self.assertEqual(b.pi('pitarget', ' text '), (len('pitarget'), ' text ')) + def test_late_tail(self): + # Issue #37399: The tail of an ignored comment could overwrite the text before it. + class TreeBuilderSubclass(ET.TreeBuilder): + pass + + xml = "texttail" + a = ET.fromstring(xml) + self.assertEqual(a.text, "texttail") + + parser = ET.XMLParser(target=TreeBuilderSubclass()) + parser.feed(xml) + a = parser.close() + self.assertEqual(a.text, "texttail") + + xml = "texttail" + a = ET.fromstring(xml) + self.assertEqual(a.text, "texttail") + + xml = "texttail" + parser = ET.XMLParser(target=TreeBuilderSubclass()) + parser.feed(xml) + a = parser.close() + self.assertEqual(a.text, "texttail") + + def test_late_tail_mix_pi_comments(self): + # Issue #37399: The tail of an ignored comment could overwrite the text before it. + # Test appending tails to comments/pis. + class TreeBuilderSubclass(ET.TreeBuilder): + pass + + xml = "text \ntail" + parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True)) + parser.feed(xml) + a = parser.close() + self.assertEqual(a[0].text, ' comment ') + self.assertEqual(a[0].tail, '\ntail') + self.assertEqual(a.text, "text ") + + parser = ET.XMLParser(target=TreeBuilderSubclass(insert_comments=True)) + parser.feed(xml) + a = parser.close() + self.assertEqual(a[0].text, ' comment ') + self.assertEqual(a[0].tail, '\ntail') + self.assertEqual(a.text, "text ") + + xml = "text\ntail" + parser = ET.XMLParser(target=ET.TreeBuilder(insert_pis=True)) + parser.feed(xml) + a = parser.close() + self.assertEqual(a[0].text, 'pi data') + self.assertEqual(a[0].tail, 'tail') + self.assertEqual(a.text, "text\n") + + parser = ET.XMLParser(target=TreeBuilderSubclass(insert_pis=True)) + parser.feed(xml) + a = parser.close() + self.assertEqual(a[0].text, 'pi data') + self.assertEqual(a[0].tail, 'tail') + self.assertEqual(a.text, "text\n") + def test_treebuilder_elementfactory_none(self): parser = ET.XMLParser(target=ET.TreeBuilder(element_factory=None)) parser.feed(self.sample1) diff --git a/Lib/test/test_xxtestfuzz.py b/Lib/test/test_xxtestfuzz.py index 532f5fe72aa5f0..15924aaeff3851 100644 --- a/Lib/test/test_xxtestfuzz.py +++ b/Lib/test/test_xxtestfuzz.py @@ -16,6 +16,8 @@ def test_sample_input_smoke_test(self): _xxtestfuzz.run(b" ") _xxtestfuzz.run(b"x") _xxtestfuzz.run(b"1") + _xxtestfuzz.run(b"AAAAAAA") + _xxtestfuzz.run(b"AAAAAA\0") if __name__ == "__main__": diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index bf5bb4d0f13e3d..76e2f647c607bf 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -4,11 +4,12 @@ import os import pathlib import posixpath -import shutil import struct -import tempfile +import subprocess +import sys import time import unittest +import unittest.mock as mock import zipfile @@ -1739,6 +1740,16 @@ def test_seek_tell(self): fp.seek(0, os.SEEK_SET) self.assertEqual(fp.tell(), 0) + @requires_bz2 + def test_decompress_without_3rd_party_library(self): + data = b'PK\x05\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + zip_file = io.BytesIO(data) + with zipfile.ZipFile(zip_file, 'w', compression=zipfile.ZIP_BZIP2) as zf: + zf.writestr('a.txt', b'a') + with mock.patch('zipfile.bz2', None): + with zipfile.ZipFile(zip_file) as zf: + self.assertRaises(RuntimeError, zf.extract, 'a.txt') + def tearDown(self): unlink(TESTFN) unlink(TESTFN2) @@ -2399,99 +2410,153 @@ def test_extract_command(self): consume = tuple -def add_dirs(zipfile): +def add_dirs(zf): """ - Given a writable zipfile, inject directory entries for + Given a writable zip file zf, inject directory entries for any directories implied by the presence of children. """ - names = zipfile.namelist() - consume( - zipfile.writestr(name + "/", b"") - for name in map(posixpath.dirname, names) - if name and name + "/" not in names - ) - return zipfile + for name in zipfile.Path._implied_dirs(zf.namelist()): + zf.writestr(name, b"") + return zf -def build_abcde_files(): +def build_alpharep_fixture(): """ Create a zip file with this structure: . ├── a.txt - └── b - ├── c.txt - └── d - └── e.txt + ├── b + │ ├── c.txt + │ ├── d + │ │ └── e.txt + │ └── f.txt + └── g + └── h + └── i.txt + + This fixture has the following key characteristics: + + - a file at the root (a) + - a file two levels deep (b/d/e) + - multiple files in a directory (b/c, b/f) + - a directory containing only a directory (g/h) + + "alpha" because it uses alphabet + "rep" because it's a representative example """ data = io.BytesIO() zf = zipfile.ZipFile(data, "w") zf.writestr("a.txt", b"content of a") zf.writestr("b/c.txt", b"content of c") zf.writestr("b/d/e.txt", b"content of e") - zf.filename = "abcde.zip" + zf.writestr("b/f.txt", b"content of f") + zf.writestr("g/h/i.txt", b"content of i") + zf.filename = "alpharep.zip" return zf +class TestExecutablePrependedZip(unittest.TestCase): + """Test our ability to open zip files with an executable prepended.""" + + def setUp(self): + self.exe_zip = findfile('exe_with_zip', subdir='ziptestdata') + self.exe_zip64 = findfile('exe_with_z64', subdir='ziptestdata') + + def _test_zip_works(self, name): + # bpo-28494 sanity check: ensure is_zipfile works on these. + self.assertTrue(zipfile.is_zipfile(name), + f'is_zipfile failed on {name}') + # Ensure we can operate on these via ZipFile. + with zipfile.ZipFile(name) as zipfp: + for n in zipfp.namelist(): + data = zipfp.read(n) + self.assertIn(b'FAVORITE_NUMBER', data) + + def test_read_zip_with_exe_prepended(self): + self._test_zip_works(self.exe_zip) + + def test_read_zip64_with_exe_prepended(self): + self._test_zip_works(self.exe_zip64) + + @unittest.skipUnless(sys.executable, 'sys.executable required.') + @unittest.skipUnless(os.access('/bin/bash', os.X_OK), + 'Test relies on #!/bin/bash working.') + def test_execute_zip2(self): + output = subprocess.check_output([self.exe_zip, sys.executable]) + self.assertIn(b'number in executable: 5', output) + + @unittest.skipUnless(sys.executable, 'sys.executable required.') + @unittest.skipUnless(os.access('/bin/bash', os.X_OK), + 'Test relies on #!/bin/bash working.') + def test_execute_zip64(self): + output = subprocess.check_output([self.exe_zip64, sys.executable]) + self.assertIn(b'number in executable: 5', output) + + class TestPath(unittest.TestCase): def setUp(self): self.fixtures = contextlib.ExitStack() self.addCleanup(self.fixtures.close) - def zipfile_abcde(self): + def zipfile_alpharep(self): with self.subTest(): - yield build_abcde_files() + yield build_alpharep_fixture() with self.subTest(): - yield add_dirs(build_abcde_files()) + yield add_dirs(build_alpharep_fixture()) def zipfile_ondisk(self): tmpdir = pathlib.Path(self.fixtures.enter_context(temp_dir())) - for zipfile_abcde in self.zipfile_abcde(): - buffer = zipfile_abcde.fp - zipfile_abcde.close() - path = tmpdir / zipfile_abcde.filename + for alpharep in self.zipfile_alpharep(): + buffer = alpharep.fp + alpharep.close() + path = tmpdir / alpharep.filename with path.open("wb") as strm: strm.write(buffer.getvalue()) yield path - def test_iterdir_istype(self): - for zipfile_abcde in self.zipfile_abcde(): - root = zipfile.Path(zipfile_abcde) + def test_iterdir_and_types(self): + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) assert root.is_dir() - a, b = root.iterdir() + a, b, g = root.iterdir() assert a.is_file() assert b.is_dir() - c, d = b.iterdir() - assert c.is_file() + assert g.is_dir() + c, f, d = b.iterdir() + assert c.is_file() and f.is_file() e, = d.iterdir() assert e.is_file() + h, = g.iterdir() + i, = h.iterdir() + assert i.is_file() def test_open(self): - for zipfile_abcde in self.zipfile_abcde(): - root = zipfile.Path(zipfile_abcde) - a, b = root.iterdir() + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) + a, b, g = root.iterdir() with a.open() as strm: data = strm.read() assert data == b"content of a" def test_read(self): - for zipfile_abcde in self.zipfile_abcde(): - root = zipfile.Path(zipfile_abcde) - a, b = root.iterdir() + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) + a, b, g = root.iterdir() assert a.read_text() == "content of a" assert a.read_bytes() == b"content of a" def test_joinpath(self): - for zipfile_abcde in self.zipfile_abcde(): - root = zipfile.Path(zipfile_abcde) + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) a = root.joinpath("a") assert a.is_file() e = root.joinpath("b").joinpath("d").joinpath("e.txt") assert e.read_text() == "content of e" def test_traverse_truediv(self): - for zipfile_abcde in self.zipfile_abcde(): - root = zipfile.Path(zipfile_abcde) + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) a = root / "a" assert a.is_file() e = root / "b" / "d" / "e.txt" @@ -2506,15 +2571,27 @@ def test_pathlike_construction(self): zipfile.Path(pathlike) def test_traverse_pathlike(self): - for zipfile_abcde in self.zipfile_abcde(): - root = zipfile.Path(zipfile_abcde) + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) root / pathlib.Path("a") def test_parent(self): - for zipfile_abcde in self.zipfile_abcde(): - root = zipfile.Path(zipfile_abcde) + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) assert (root / 'a').parent.at == '' assert (root / 'a' / 'b').parent.at == 'a/' + def test_dir_parent(self): + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) + assert (root / 'b').parent.at == '' + assert (root / 'b/').parent.at == '' + + def test_missing_dir_parent(self): + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) + assert (root / 'missing dir/').parent.at == '' + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/ziptestdata/README.md b/Lib/test/ziptestdata/README.md new file mode 100644 index 00000000000000..6b9147db76e178 --- /dev/null +++ b/Lib/test/ziptestdata/README.md @@ -0,0 +1,35 @@ +# Test data for `test_zipfile` + +The test executables in this directory are created manually from header.sh and +the `testdata_module_inside_zip.py` file. You must have infozip's zip utility +installed (`apt install zip` on Debian). + +## Purpose + +These are used to test executable files with an appended zipfile, in a scenario +where the executable is _not_ a Python interpreter itself so our automatic +zipimport machinery (that'd look for `__main__.py`) is not being used. + +## Updating the test executables + +If you update header.sh or the testdata_module_inside_zip.py file, rerun the +commands below. These are expected to be rarely changed, if ever. + +### Standard old format (2.0) zip file + +``` +zip -0 zip2.zip testdata_module_inside_zip.py +cat header.sh zip2.zip >exe_with_zip +rm zip2.zip +``` + +### Modern format (4.5) zip64 file + +Redirecting from stdin forces infozip's zip tool to create a zip64. + +``` +zip -0 zip64.zip +cat header.sh zip64.zip >exe_with_z64 +rm zip64.zip +``` + diff --git a/Lib/test/ziptestdata/exe_with_z64 b/Lib/test/ziptestdata/exe_with_z64 new file mode 100755 index 00000000000000..82b03cf39d919d Binary files /dev/null and b/Lib/test/ziptestdata/exe_with_z64 differ diff --git a/Lib/test/ziptestdata/exe_with_zip b/Lib/test/ziptestdata/exe_with_zip new file mode 100755 index 00000000000000..c833cdf9f934b0 Binary files /dev/null and b/Lib/test/ziptestdata/exe_with_zip differ diff --git a/Lib/test/ziptestdata/header.sh b/Lib/test/ziptestdata/header.sh new file mode 100755 index 00000000000000..52dc91acf7400c --- /dev/null +++ b/Lib/test/ziptestdata/header.sh @@ -0,0 +1,24 @@ +#!/bin/bash +INTERPRETER_UNDER_TEST="$1" +if [[ ! -x "${INTERPRETER_UNDER_TEST}" ]]; then + echo "Interpreter must be the command line argument." + exit 4 +fi +EXECUTABLE="$0" exec "${INTERPRETER_UNDER_TEST}" -E - < U: @runtime_checkable class SupportsInt(Protocol): + """An ABC with one abstract method __int__.""" __slots__ = () @abstractmethod @@ -1516,6 +1523,7 @@ def __int__(self) -> int: @runtime_checkable class SupportsFloat(Protocol): + """An ABC with one abstract method __float__.""" __slots__ = () @abstractmethod @@ -1525,6 +1533,7 @@ def __float__(self) -> float: @runtime_checkable class SupportsComplex(Protocol): + """An ABC with one abstract method __complex__.""" __slots__ = () @abstractmethod @@ -1534,6 +1543,7 @@ def __complex__(self) -> complex: @runtime_checkable class SupportsBytes(Protocol): + """An ABC with one abstract method __bytes__.""" __slots__ = () @abstractmethod @@ -1543,6 +1553,7 @@ def __bytes__(self) -> bytes: @runtime_checkable class SupportsIndex(Protocol): + """An ABC with one abstract method __index__.""" __slots__ = () @abstractmethod @@ -1552,6 +1563,7 @@ def __index__(self) -> int: @runtime_checkable class SupportsAbs(Protocol[T_co]): + """An ABC with one abstract method __abs__ that is covariant in its return type.""" __slots__ = () @abstractmethod @@ -1561,6 +1573,7 @@ def __abs__(self) -> T_co: @runtime_checkable class SupportsRound(Protocol[T_co]): + """An ABC with one abstract method __round__ that is covariant in its return type.""" __slots__ = () @abstractmethod @@ -1587,7 +1600,7 @@ def _make_nmtuple(name, types): '_fields', '_field_defaults', '_field_types', '_make', '_replace', '_asdict', '_source') -_special = ('__module__', '__name__', '__qualname__', '__annotations__') +_special = ('__module__', '__name__', '__annotations__') class NamedTupleMeta(type): @@ -1647,35 +1660,63 @@ class Employee(NamedTuple): """ _root = True - def __new__(self, typename, fields=None, **kwargs): + def __new__(*args, **kwargs): + if not args: + raise TypeError('NamedTuple.__new__(): not enough arguments') + cls, *args = args # allow the "cls" keyword be passed + if args: + typename, *args = args # allow the "typename" keyword be passed + elif 'typename' in kwargs: + typename = kwargs.pop('typename') + import warnings + warnings.warn("Passing 'typename' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError("NamedTuple.__new__() missing 1 required positional " + "argument: 'typename'") + if args: + try: + fields, = args # allow the "fields" keyword be passed + except ValueError: + raise TypeError(f'NamedTuple.__new__() takes from 2 to 3 ' + f'positional arguments but {len(args) + 2} ' + f'were given') from None + elif 'fields' in kwargs and len(kwargs) == 1: + fields = kwargs.pop('fields') + import warnings + warnings.warn("Passing 'fields' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + fields = None + if fields is None: fields = kwargs.items() elif kwargs: raise TypeError("Either list of fields or keywords" " can be provided to NamedTuple, not both") return _make_nmtuple(typename, fields) + __new__.__text_signature__ = '($cls, typename, fields=None, /, **kwargs)' -def _dict_new(cls, *args, **kwargs): +def _dict_new(cls, /, *args, **kwargs): return dict(*args, **kwargs) -def _typeddict_new(cls, _typename, _fields=None, **kwargs): - total = kwargs.pop('total', True) - if _fields is None: - _fields = kwargs +def _typeddict_new(cls, typename, fields=None, /, *, total=True, **kwargs): + if fields is None: + fields = kwargs elif kwargs: raise TypeError("TypedDict takes either a dict or keyword arguments," " but not both") - ns = {'__annotations__': dict(_fields), '__total__': total} + ns = {'__annotations__': dict(fields), '__total__': total} try: # Setting correct module is necessary to make typed dict classes pickleable. ns['__module__'] = sys._getframe(1).f_globals.get('__name__', '__main__') except (AttributeError, ValueError): pass - return _TypedDictMeta(_typename, (), ns) + return _TypedDictMeta(typename, (), ns) def _check_fails(cls, other): @@ -1789,11 +1830,13 @@ class IO(Generic[AnyStr]): __slots__ = () - @abstractproperty + @property + @abstractmethod def mode(self) -> str: pass - @abstractproperty + @property + @abstractmethod def name(self) -> str: pass @@ -1889,23 +1932,28 @@ class TextIO(IO[str]): __slots__ = () - @abstractproperty + @property + @abstractmethod def buffer(self) -> BinaryIO: pass - @abstractproperty + @property + @abstractmethod def encoding(self) -> str: pass - @abstractproperty + @property + @abstractmethod def errors(self) -> Optional[str]: pass - @abstractproperty + @property + @abstractmethod def line_buffering(self) -> bool: pass - @abstractproperty + @property + @abstractmethod def newlines(self) -> Any: pass diff --git a/Lib/unittest/async_case.py b/Lib/unittest/async_case.py index a3c8bfb9eca758..1bc1312c8c2ee9 100644 --- a/Lib/unittest/async_case.py +++ b/Lib/unittest/async_case.py @@ -89,8 +89,9 @@ def _callMaybeAsync(self, func, /, *args, **kwargs): else: return ret - async def _asyncioLoopRunner(self): - queue = self._asyncioCallsQueue + async def _asyncioLoopRunner(self, fut): + self._asyncioCallsQueue = queue = asyncio.Queue() + fut.set_result(None) while True: query = await queue.get() queue.task_done() @@ -113,8 +114,9 @@ def _setupAsyncioLoop(self): asyncio.set_event_loop(loop) loop.set_debug(True) self._asyncioTestLoop = loop - self._asyncioCallsQueue = asyncio.Queue(loop=loop) - self._asyncioCallsTask = loop.create_task(self._asyncioLoopRunner()) + 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 diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index b363c635100726..b639c64d02a7aa 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -10,6 +10,7 @@ import collections import contextlib import traceback +import types from . import result from .util import (strclass, safe_repr, _count_diff_all_purpose, @@ -122,6 +123,10 @@ def skip_wrapper(*args, **kwargs): test_item.__unittest_skip__ = True test_item.__unittest_skip_why__ = reason return test_item + if isinstance(reason, types.FunctionType): + test_item = reason + reason = '' + return decorator(test_item) return decorator def skipIf(condition, reason): diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index c2802726d75d9c..488ab1c23de423 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -46,10 +46,9 @@ _safe_super = super def _is_async_obj(obj): - if getattr(obj, '__code__', None): - return asyncio.iscoroutinefunction(obj) or inspect.isawaitable(obj) - else: + if _is_instance_mock(obj) and not isinstance(obj, AsyncMock): return False + return asyncio.iscoroutinefunction(obj) or inspect.isawaitable(obj) def _is_async_func(func): @@ -72,6 +71,15 @@ def _is_exception(obj): ) +def _extract_mock(obj): + # Autospecced functions will return a FunctionType with "mock" attribute + # which is the actual mock object that needs to be used. + if isinstance(obj, FunctionTypes) and hasattr(obj, 'mock'): + return obj.mock + else: + return obj + + def _get_signature_object(func, as_instance, eat_self): """ Given an arbitrary, possibly callable object, try to create a suitable @@ -238,7 +246,6 @@ def _setup_async_mock(mock): mock.await_count = 0 mock.await_args = None mock.await_args_list = _CallList() - mock.awaited = _AwaitEvent(mock) # Mock is not configured yet so the attributes are set # to a function and then the corresponding mock helper function @@ -346,13 +353,7 @@ def __repr__(self): def _check_and_set_parent(parent, value, name, new_name): - # function passed to create_autospec will have mock - # attribute attached to which parent must be set - if isinstance(value, FunctionTypes): - try: - value = value.mock - except AttributeError: - pass + value = _extract_mock(value) if not _is_instance_mock(value): return False @@ -413,7 +414,7 @@ def __new__(cls, /, *args, **kw): if _is_async_obj(bound_args[spec_arg[0]]): bases = (AsyncMockMixin, cls,) new = type(cls.__name__, bases, {'__doc__': cls.__doc__}) - instance = object.__new__(new) + instance = _safe_super(NonCallableMock, cls).__new__(new) return instance @@ -467,10 +468,12 @@ def attach_mock(self, mock, attribute): Attach a mock as an attribute of this one, replacing its name and parent. Calls to the attached mock will be recorded in the `method_calls` and `mock_calls` attributes of this one.""" - mock._mock_parent = None - mock._mock_new_parent = None - mock._mock_name = '' - mock._mock_new_name = None + inner_mock = _extract_mock(mock) + + inner_mock._mock_parent = None + inner_mock._mock_new_parent = None + inner_mock._mock_name = '' + inner_mock._mock_new_name = None setattr(self, attribute, mock) @@ -799,6 +802,35 @@ def _format_mock_failure_message(self, args, kwargs, action='call'): return message % (action, expected_string, actual_string) + def _get_call_signature_from_name(self, name): + """ + * If call objects are asserted against a method/function like obj.meth1 + then there could be no name for the call object to lookup. Hence just + return the spec_signature of the method/function being asserted against. + * If the name is not empty then remove () and split by '.' to get + list of names to iterate through the children until a potential + match is found. A child mock is created only during attribute access + so if we get a _SpecState then no attributes of the spec were accessed + and can be safely exited. + """ + if not name: + return self._spec_signature + + sig = None + names = name.replace('()', '').split('.') + children = self._mock_children + + for name in names: + child = children.get(name) + if child is None or isinstance(child, _SpecState): + break + else: + children = child._mock_children + sig = child._spec_signature + + return sig + + def _call_matcher(self, _call): """ Given a call (or simply an (args, kwargs) tuple), return a @@ -806,7 +838,12 @@ def _call_matcher(self, _call): This is a best effort method which relies on the spec's signature, if available, or falls back on the arguments themselves. """ - sig = self._spec_signature + + if isinstance(_call, tuple) and len(_call) > 2: + sig = self._get_call_signature_from_name(_call[0]) + else: + sig = self._spec_signature + if sig is not None: if len(_call) == 2: name = '' @@ -835,7 +872,7 @@ def assert_called(self): """ if self.call_count == 0: msg = ("Expected '%s' to have been called." % - self._mock_name or 'mock') + (self._mock_name or 'mock')) raise AssertionError(msg) def assert_called_once(self): @@ -849,7 +886,7 @@ def assert_called_once(self): raise AssertionError(msg) def assert_called_with(self, /, *args, **kwargs): - """assert that the mock was called with the specified arguments. + """assert that the last call was made with the specified arguments. Raises an AssertionError if the args and keyword args passed in are different to the last call to the mock.""" @@ -893,13 +930,21 @@ def assert_has_calls(self, calls, any_order=False): If `any_order` is True then the calls can be in any order, but they must all appear in `mock_calls`.""" expected = [self._call_matcher(c) for c in calls] - cause = expected if isinstance(expected, Exception) else None + cause = next((e for e in expected if isinstance(e, Exception)), None) all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls) if not any_order: if expected not in all_calls: + if cause is None: + problem = 'Calls not found.' + else: + problem = ('Error processing expected calls.\n' + 'Errors: {}').format( + [e if isinstance(e, Exception) else None + for e in expected]) raise AssertionError( - 'Calls not found.\nExpected: %r%s' - % (_CallList(calls), self._calls_repr(prefix="Actual")) + f'{problem}\n' + f'Expected: {_CallList(calls)}' + f'{self._calls_repr(prefix="Actual").rstrip(".")}' ) from cause return @@ -949,13 +994,19 @@ def _get_child_mock(self, /, **kw): _type = type(self) if issubclass(_type, MagicMock) and _new_name in _async_method_magics: + # Any asynchronous magic becomes an AsyncMock klass = AsyncMock - if issubclass(_type, AsyncMockMixin): - klass = MagicMock - if not issubclass(_type, CallableMixin): + elif issubclass(_type, AsyncMockMixin): + if (_new_name in _all_sync_magics or + self._mock_methods and _new_name in self._mock_methods): + # Any synchronous method on AsyncMock becomes a MagicMock + klass = MagicMock + else: + klass = AsyncMock + elif not issubclass(_type, CallableMixin): if issubclass(_type, NonCallableMagicMock): klass = MagicMock - elif issubclass(_type, NonCallableMock) : + elif issubclass(_type, NonCallableMock): klass = Mock else: klass = _type.__mro__[1] @@ -1020,14 +1071,20 @@ def __call__(self, /, *args, **kwargs): # can't use self in-case a function / method we are mocking uses self # in the signature self._mock_check_sig(*args, **kwargs) + self._increment_mock_call(*args, **kwargs) return self._mock_call(*args, **kwargs) def _mock_call(self, /, *args, **kwargs): + return self._execute_mock_call(*args, **kwargs) + + def _increment_mock_call(self, /, *args, **kwargs): self.called = True self.call_count += 1 # handle call_args + # needs to be set here so assertions on call arguments pass before + # execution in the case of awaited calls _call = _Call((args, kwargs), two=True) self.call_args = _call self.call_args_list.append(_call) @@ -1067,6 +1124,10 @@ def _mock_call(self, /, *args, **kwargs): # follow the parental chain: _new_parent = _new_parent._mock_new_parent + def _execute_mock_call(self, /, *args, **kwargs): + # seperate from _increment_mock_call so that awaited functions are + # executed seperately from their call + effect = self.side_effect if effect is not None: if _is_exception(effect): @@ -1592,8 +1653,9 @@ def patch( is patched with a `new` object. When the function/with statement exits the patch is undone. - If `new` is omitted, then the target is replaced with a - `MagicMock`. If `patch` is used as a decorator and `new` is + If `new` is omitted, then the target is replaced with an + `AsyncMock if the patched object is an async function or a + `MagicMock` otherwise. If `patch` is used as a decorator and `new` is omitted, the created mock is passed in as an extra argument to the decorated function. If `patch` is used as a context manager the created mock is returned by the context manager. @@ -1611,8 +1673,8 @@ def patch( patch to pass in the object being mocked as the spec/spec_set object. `new_callable` allows you to specify a different class, or callable object, - that will be called to create the `new` object. By default `MagicMock` is - used. + that will be called to create the `new` object. By default `AsyncMock` is + used for async functions and `MagicMock` for the rest. A more powerful form of `spec` is `autospec`. If you set `autospec=True` then the mock will be created with a spec from the object being replaced. @@ -1811,6 +1873,7 @@ def _patch_stopall(): "round trunc floor ceil " "bool next " "fspath " + "aiter " ) numerics = ( @@ -1828,7 +1891,7 @@ def _patch_stopall(): '__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__', '__getstate__', '__setstate__', '__getformat__', '__setformat__', '__repr__', '__dir__', '__subclasses__', '__format__', - '__getnewargs_ex__', '__aenter__', '__aexit__', '__anext__', '__aiter__', + '__getnewargs_ex__', } @@ -1847,10 +1910,12 @@ def method(self, /, *args, **kw): # Magic methods used for async `with` statements _async_method_magics = {"__aenter__", "__aexit__", "__anext__"} -# `__aiter__` is a plain function but used with async calls -_async_magics = _async_method_magics | {"__aiter__"} +# Magic methods that are only used with async calls but are synchronous functions themselves +_sync_async_magics = {"__aiter__"} +_async_magics = _async_method_magics | _sync_async_magics -_all_magics = _magics | _non_defaults +_all_sync_magics = _magics | _non_defaults +_all_magics = _all_sync_magics | _async_magics _unsupported_magics = { '__getattr__', '__setattr__', @@ -1935,9 +2000,9 @@ def _set_return_value(mock, method, name): method.return_value = fixed return - return_calulator = _calculate_return_value.get(name) - if return_calulator is not None: - return_value = return_calulator(mock) + return_calculator = _calculate_return_value.get(name) + if return_calculator is not None: + return_value = return_calculator(mock) method.return_value = return_value return @@ -1947,7 +2012,7 @@ def _set_return_value(mock, method, name): -class MagicMixin(object): +class MagicMixin(Base): def __init__(self, /, *args, **kw): self._mock_set_magics() # make magic work for kwargs in init _safe_super(MagicMixin, self).__init__(*args, **kw) @@ -1955,13 +2020,14 @@ def __init__(self, /, *args, **kw): def _mock_set_magics(self): - these_magics = _magics + orig_magics = _magics | _async_method_magics + these_magics = orig_magics if getattr(self, "_mock_methods", None) is not None: - these_magics = _magics.intersection(self._mock_methods) + these_magics = orig_magics.intersection(self._mock_methods) remove_magics = set() - remove_magics = _magics - these_magics + remove_magics = orig_magics - these_magics for entry in remove_magics: if entry in type(self).__dict__: @@ -1989,33 +2055,13 @@ def mock_add_spec(self, spec, spec_set=False): self._mock_set_magics() -class AsyncMagicMixin: +class AsyncMagicMixin(MagicMixin): def __init__(self, /, *args, **kw): - self._mock_set_async_magics() # make magic work for kwargs in init + self._mock_set_magics() # make magic work for kwargs in init _safe_super(AsyncMagicMixin, self).__init__(*args, **kw) - self._mock_set_async_magics() # fix magic broken by upper level init - - def _mock_set_async_magics(self): - these_magics = _async_magics - - if getattr(self, "_mock_methods", None) is not None: - these_magics = _async_magics.intersection(self._mock_methods) - remove_magics = _async_magics - these_magics - - for entry in remove_magics: - if entry in type(self).__dict__: - # remove unneeded magic methods - delattr(self, entry) - - # don't overwrite existing attributes if called a second time - these_magics = these_magics - set(type(self).__dict__) - - _type = type(self) - for entry in these_magics: - setattr(_type, entry, MagicProxy(entry, self)) - + self._mock_set_magics() # fix magic broken by upper level init -class MagicMock(MagicMixin, AsyncMagicMixin, Mock): +class MagicMock(MagicMixin, Mock): """ MagicMock is a subclass of Mock with default implementations of most of the magic methods. You can use MagicMock without having to @@ -2037,7 +2083,7 @@ def mock_add_spec(self, spec, spec_set=False): -class MagicProxy(object): +class MagicProxy(Base): def __init__(self, name, parent): self.name = name self.parent = parent @@ -2056,7 +2102,6 @@ def __get__(self, obj, _type=None): class AsyncMockMixin(Base): - awaited = _delegating_property('awaited') await_count = _delegating_property('await_count') await_args = _delegating_property('await_args') await_args_list = _delegating_property('await_args_list') @@ -2070,7 +2115,6 @@ def __init__(self, /, *args, **kwargs): # It is set through __dict__ because when spec_set is True, this # attribute is likely undefined. self.__dict__['_is_coroutine'] = asyncio.coroutines._is_coroutine - self.__dict__['_mock_awaited'] = _AwaitEvent(self) self.__dict__['_mock_await_count'] = 0 self.__dict__['_mock_await_args'] = None self.__dict__['_mock_await_args_list'] = _CallList() @@ -2099,7 +2143,6 @@ async def proxy(): self.await_count += 1 self.await_args = _call self.await_args_list.append(_call) - await self.awaited._notify() return await proxy() @@ -2175,12 +2218,20 @@ def assert_has_awaits(self, calls, any_order=False): they must all appear in :attr:`await_args_list`. """ expected = [self._call_matcher(c) for c in calls] - cause = expected if isinstance(expected, Exception) else None + cause = next((e for e in expected if isinstance(e, Exception)), None) all_awaits = _CallList(self._call_matcher(c) for c in self.await_args_list) if not any_order: if expected not in all_awaits: + if cause is None: + problem = 'Awaits not found.' + else: + problem = ('Error processing expected awaits.\n' + 'Errors: {}').format( + [e if isinstance(e, Exception) else None + for e in expected]) raise AssertionError( - f'Awaits not found.\nExpected: {_CallList(calls)}\n' + f'{problem}\n' + f'Expected: {_CallList(calls)}\n' f'Actual: {self.await_args_list}' ) from cause return @@ -2281,7 +2332,7 @@ def _format_call_signature(name, args, kwargs): formatted_args = '' args_string = ', '.join([repr(arg) for arg in args]) kwargs_string = ', '.join([ - '%s=%r' % (key, value) for key, value in sorted(kwargs.items()) + '%s=%r' % (key, value) for key, value in kwargs.items() ]) if args_string: formatted_args = args_string @@ -2425,6 +2476,12 @@ def __getattr__(self, attr): return _Call(name=name, parent=self, from_kall=False) + def __getattribute__(self, attr): + if attr in tuple.__dict__: + raise AttributeError + return tuple.__getattribute__(self, attr) + + def count(self, /, *args, **kwargs): return self.__getattr__('count')(*args, **kwargs) @@ -2767,7 +2824,7 @@ class PropertyMock(Mock): def _get_child_mock(self, /, **kwargs): return MagicMock(**kwargs) - def __get__(self, obj, obj_type): + def __get__(self, obj, obj_type=None): return self() def __set__(self, obj, val): self(val) @@ -2818,35 +2875,3 @@ async def __anext__(self): except StopIteration: pass raise StopAsyncIteration - - -class _AwaitEvent: - def __init__(self, mock): - self._mock = mock - self._condition = None - - async def _notify(self): - condition = self._get_condition() - try: - await condition.acquire() - condition.notify_all() - finally: - condition.release() - - def _get_condition(self): - """ - Creation of condition is delayed, to minimize the chance of using the - wrong loop. - A user may create a mock with _AwaitEvent before selecting the - execution loop. Requiring a user to delay creation is error-prone and - inflexible. Instead, condition is created when user actually starts to - use the mock. - """ - # No synchronization is needed: - # - asyncio is thread unsafe - # - there are no awaits here, method will be executed without - # switching asyncio context. - if self._condition is None: - self._condition = asyncio.Condition() - - return self._condition diff --git a/Lib/unittest/test/test_discovery.py b/Lib/unittest/test/test_discovery.py index 204043b493b5d2..16e081e1fb76ec 100644 --- a/Lib/unittest/test/test_discovery.py +++ b/Lib/unittest/test/test_discovery.py @@ -723,11 +723,13 @@ class Module(object): original_listdir = os.listdir original_isfile = os.path.isfile original_isdir = os.path.isdir + original_realpath = os.path.realpath def cleanup(): os.listdir = original_listdir os.path.isfile = original_isfile os.path.isdir = original_isdir + os.path.realpath = original_realpath del sys.modules['foo'] if full_path in sys.path: sys.path.remove(full_path) @@ -742,6 +744,10 @@ def isdir(_): os.listdir = listdir os.path.isfile = isfile os.path.isdir = isdir + if os.name == 'nt': + # ntpath.realpath may inject path prefixes when failing to + # resolve real files, so we substitute abspath() here instead. + os.path.realpath = os.path.abspath return full_path def test_detect_module_clash(self): diff --git a/Lib/unittest/test/test_skipping.py b/Lib/unittest/test/test_skipping.py index 71f7b70e479d2e..1c178a95f750ff 100644 --- a/Lib/unittest/test/test_skipping.py +++ b/Lib/unittest/test/test_skipping.py @@ -255,6 +255,17 @@ def test_1(self): suite.run(result) self.assertEqual(result.skipped, [(test, "testing")]) + def test_skip_without_reason(self): + class Foo(unittest.TestCase): + @unittest.skip + def test_1(self): + pass + + result = unittest.TestResult() + test = Foo("test_1") + suite = unittest.TestSuite([test]) + suite.run(result) + self.assertEqual(result.skipped, [(test, "")]) if __name__ == "__main__": unittest.main() diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py index fa906e4f7152f8..7671d55a8cfba8 100644 --- a/Lib/unittest/test/testmock/testasync.py +++ b/Lib/unittest/test/testmock/testasync.py @@ -1,9 +1,10 @@ import asyncio import inspect +import re import unittest -from unittest.mock import (call, AsyncMock, patch, MagicMock, create_autospec, - _AwaitEvent) +from unittest.mock import (ANY, call, AsyncMock, patch, MagicMock, Mock, + create_autospec, sentinel, _CallList) def tearDownModule(): @@ -18,6 +19,10 @@ async def async_method(self): def normal_method(self): pass +class AwaitableClass: + def __await__(self): + yield + async def async_func(): pass @@ -160,6 +165,10 @@ def test_create_autospec_instance(self): with self.assertRaises(RuntimeError): create_autospec(async_func, instance=True) + def test_create_autospec_awaitable_class(self): + awaitable_mock = create_autospec(spec=AwaitableClass()) + self.assertIsInstance(create_autospec(awaitable_mock), AsyncMock) + def test_create_autospec(self): spec = create_autospec(async_func_args) awaitable = spec(1, 2, c=3) @@ -169,7 +178,6 @@ async def main(): self.assertEqual(spec.await_count, 0) self.assertIsNone(spec.await_args) self.assertEqual(spec.await_args_list, []) - self.assertIsInstance(spec.awaited, _AwaitEvent) spec.assert_not_awaited() asyncio.run(main()) @@ -199,7 +207,6 @@ async def test_async(): self.assertEqual(mock_method.await_count, 0) self.assertEqual(mock_method.await_args_list, []) self.assertIsNone(mock_method.await_args) - self.assertIsInstance(mock_method.awaited, _AwaitEvent) mock_method.assert_not_awaited() await awaitable @@ -221,33 +228,50 @@ async def test_async(): class AsyncSpecTest(unittest.TestCase): - def test_spec_as_async_positional_magicmock(self): - mock = MagicMock(async_func) - self.assertIsInstance(mock, MagicMock) - m = mock() - self.assertTrue(inspect.isawaitable(m)) - asyncio.run(m) - - def test_spec_as_async_kw_magicmock(self): - mock = MagicMock(spec=async_func) - self.assertIsInstance(mock, MagicMock) - m = mock() - self.assertTrue(inspect.isawaitable(m)) - asyncio.run(m) - - def test_spec_as_async_kw_AsyncMock(self): - mock = AsyncMock(spec=async_func) - self.assertIsInstance(mock, AsyncMock) - m = mock() - self.assertTrue(inspect.isawaitable(m)) - asyncio.run(m) - - def test_spec_as_async_positional_AsyncMock(self): - mock = AsyncMock(async_func) - self.assertIsInstance(mock, AsyncMock) - m = mock() - self.assertTrue(inspect.isawaitable(m)) - asyncio.run(m) + def test_spec_normal_methods_on_class(self): + def inner_test(mock_type): + mock = mock_type(AsyncClass) + self.assertIsInstance(mock.async_method, AsyncMock) + self.assertIsInstance(mock.normal_method, MagicMock) + + for mock_type in [AsyncMock, MagicMock]: + with self.subTest(f"test method types with {mock_type}"): + inner_test(mock_type) + + def test_spec_normal_methods_on_class_with_mock(self): + mock = Mock(AsyncClass) + self.assertIsInstance(mock.async_method, AsyncMock) + self.assertIsInstance(mock.normal_method, Mock) + + def test_spec_mock_type_kw(self): + def inner_test(mock_type): + async_mock = mock_type(spec=async_func) + self.assertIsInstance(async_mock, mock_type) + with self.assertWarns(RuntimeWarning): + # Will raise a warning because never awaited + self.assertTrue(inspect.isawaitable(async_mock())) + + sync_mock = mock_type(spec=normal_func) + self.assertIsInstance(sync_mock, mock_type) + + for mock_type in [AsyncMock, MagicMock, Mock]: + with self.subTest(f"test spec kwarg with {mock_type}"): + inner_test(mock_type) + + def test_spec_mock_type_positional(self): + def inner_test(mock_type): + async_mock = mock_type(async_func) + self.assertIsInstance(async_mock, mock_type) + with self.assertWarns(RuntimeWarning): + # Will raise a warning because never awaited + self.assertTrue(inspect.isawaitable(async_mock())) + + sync_mock = mock_type(normal_func) + self.assertIsInstance(sync_mock, mock_type) + + for mock_type in [AsyncMock, MagicMock, Mock]: + with self.subTest(f"test spec positional with {mock_type}"): + inner_test(mock_type) def test_spec_as_normal_kw_AsyncMock(self): mock = AsyncMock(spec=normal_func) @@ -321,6 +345,13 @@ def test_is_child_AsyncMock(self): self.assertIsInstance(mock.normal_method, MagicMock) self.assertIsInstance(mock, MagicMock) + def test_magicmock_lambda_spec(self): + mock_obj = MagicMock() + mock_obj.mock_func = MagicMock(spec=lambda x: x) + + with patch.object(mock_obj, "mock_func") as cm: + self.assertIsInstance(cm, MagicMock) + class AsyncArguments(unittest.TestCase): def test_add_return_value(self): @@ -359,13 +390,46 @@ def test_add_side_effect_iterable(self): RuntimeError('coroutine raised StopIteration') ) +class AsyncMagicMethods(unittest.TestCase): + def test_async_magic_methods_return_async_mocks(self): + m_mock = MagicMock() + self.assertIsInstance(m_mock.__aenter__, AsyncMock) + self.assertIsInstance(m_mock.__aexit__, AsyncMock) + self.assertIsInstance(m_mock.__anext__, AsyncMock) + # __aiter__ is actually a synchronous object + # so should return a MagicMock + self.assertIsInstance(m_mock.__aiter__, MagicMock) + + def test_sync_magic_methods_return_magic_mocks(self): + a_mock = AsyncMock() + self.assertIsInstance(a_mock.__enter__, MagicMock) + self.assertIsInstance(a_mock.__exit__, MagicMock) + self.assertIsInstance(a_mock.__next__, MagicMock) + self.assertIsInstance(a_mock.__len__, MagicMock) + + def test_magicmock_has_async_magic_methods(self): + m_mock = MagicMock() + self.assertTrue(hasattr(m_mock, "__aenter__")) + self.assertTrue(hasattr(m_mock, "__aexit__")) + self.assertTrue(hasattr(m_mock, "__anext__")) + + def test_asyncmock_has_sync_magic_methods(self): + a_mock = AsyncMock() + self.assertTrue(hasattr(a_mock, "__enter__")) + self.assertTrue(hasattr(a_mock, "__exit__")) + self.assertTrue(hasattr(a_mock, "__next__")) + self.assertTrue(hasattr(a_mock, "__len__")) + + def test_magic_methods_are_async_functions(self): + m_mock = MagicMock() + self.assertIsInstance(m_mock.__aenter__, AsyncMock) + self.assertIsInstance(m_mock.__aexit__, AsyncMock) + # AsyncMocks are also coroutine functions + self.assertTrue(asyncio.iscoroutinefunction(m_mock.__aenter__)) + self.assertTrue(asyncio.iscoroutinefunction(m_mock.__aexit__)) class AsyncContextManagerTest(unittest.TestCase): class WithAsyncContextManager: - def __init__(self): - self.entered = False - self.exited = False - async def __aenter__(self, *args, **kwargs): self.entered = True return self @@ -373,32 +437,63 @@ async def __aenter__(self, *args, **kwargs): async def __aexit__(self, *args, **kwargs): self.exited = True - def test_magic_methods_are_async_mocks(self): - mock = MagicMock(self.WithAsyncContextManager()) - self.assertIsInstance(mock.__aenter__, AsyncMock) - self.assertIsInstance(mock.__aexit__, AsyncMock) + class WithSyncContextManager: + def __enter__(self, *args, **kwargs): + return self + + def __exit__(self, *args, **kwargs): + pass + + class ProductionCode: + # Example real-world(ish) code + def __init__(self): + self.session = None + + async def main(self): + async with self.session.post('https://python.org') as response: + val = await response.json() + return val + + def test_set_return_value_of_aenter(self): + def inner_test(mock_type): + pc = self.ProductionCode() + pc.session = MagicMock(name='sessionmock') + cm = mock_type(name='magic_cm') + response = AsyncMock(name='response') + response.json = AsyncMock(return_value={'json': 123}) + cm.__aenter__.return_value = response + pc.session.post.return_value = cm + result = asyncio.run(pc.main()) + self.assertEqual(result, {'json': 123}) + + for mock_type in [AsyncMock, MagicMock]: + with self.subTest(f"test set return value of aenter with {mock_type}"): + inner_test(mock_type) def test_mock_supports_async_context_manager(self): - called = False - instance = self.WithAsyncContextManager() - mock_instance = MagicMock(instance) + def inner_test(mock_type): + called = False + cm = self.WithAsyncContextManager() + cm_mock = mock_type(cm) + + async def use_context_manager(): + nonlocal called + async with cm_mock as result: + called = True + return result - async def use_context_manager(): - nonlocal called - async with mock_instance as result: - called = True - return result - - result = asyncio.run(use_context_manager()) - self.assertFalse(instance.entered) - self.assertFalse(instance.exited) - self.assertTrue(called) - self.assertTrue(mock_instance.entered) - self.assertTrue(mock_instance.exited) - self.assertTrue(mock_instance.__aenter__.called) - self.assertTrue(mock_instance.__aexit__.called) - self.assertIsNot(mock_instance, result) - self.assertIsInstance(result, AsyncMock) + cm_result = asyncio.run(use_context_manager()) + self.assertTrue(called) + self.assertTrue(cm_mock.__aenter__.called) + self.assertTrue(cm_mock.__aexit__.called) + cm_mock.__aenter__.assert_awaited() + cm_mock.__aexit__.assert_awaited() + # We mock __aenter__ so it does not return self + self.assertIsNot(cm_mock, cm_result) + + for mock_type in [AsyncMock, MagicMock]: + with self.subTest(f"test context manager magics with {mock_type}"): + inner_test(mock_type) def test_mock_customize_async_context_manager(self): instance = self.WithAsyncContextManager() @@ -466,27 +561,30 @@ async def __anext__(self): raise StopAsyncIteration - def test_mock_aiter_and_anext(self): - instance = self.WithAsyncIterator() - mock_instance = MagicMock(instance) - - self.assertEqual(asyncio.iscoroutine(instance.__aiter__), - asyncio.iscoroutine(mock_instance.__aiter__)) - self.assertEqual(asyncio.iscoroutine(instance.__anext__), - asyncio.iscoroutine(mock_instance.__anext__)) - - iterator = instance.__aiter__() - if asyncio.iscoroutine(iterator): - iterator = asyncio.run(iterator) - - mock_iterator = mock_instance.__aiter__() - if asyncio.iscoroutine(mock_iterator): - mock_iterator = asyncio.run(mock_iterator) + def test_aiter_set_return_value(self): + mock_iter = AsyncMock(name="tester") + mock_iter.__aiter__.return_value = [1, 2, 3] + async def main(): + return [i async for i in mock_iter] + result = asyncio.run(main()) + self.assertEqual(result, [1, 2, 3]) + + def test_mock_aiter_and_anext_asyncmock(self): + def inner_test(mock_type): + instance = self.WithAsyncIterator() + mock_instance = mock_type(instance) + # Check that the mock and the real thing bahave the same + # __aiter__ is not actually async, so not a coroutinefunction + self.assertFalse(asyncio.iscoroutinefunction(instance.__aiter__)) + self.assertFalse(asyncio.iscoroutinefunction(mock_instance.__aiter__)) + # __anext__ is async + self.assertTrue(asyncio.iscoroutinefunction(instance.__anext__)) + self.assertTrue(asyncio.iscoroutinefunction(mock_instance.__anext__)) + + for mock_type in [AsyncMock, MagicMock]: + with self.subTest(f"test aiter and anext corourtine with {mock_type}"): + inner_test(mock_type) - self.assertEqual(asyncio.iscoroutine(iterator.__aiter__), - asyncio.iscoroutine(mock_iterator.__aiter__)) - self.assertEqual(asyncio.iscoroutine(iterator.__anext__), - asyncio.iscoroutine(mock_iterator.__anext__)) def test_mock_async_for(self): async def iterate(iterator): @@ -497,30 +595,203 @@ async def iterate(iterator): return accumulator expected = ["FOO", "BAR", "BAZ"] - with self.subTest("iterate through default value"): - mock_instance = MagicMock(self.WithAsyncIterator()) - self.assertEqual([], asyncio.run(iterate(mock_instance))) + def test_default(mock_type): + mock_instance = mock_type(self.WithAsyncIterator()) + self.assertEqual(asyncio.run(iterate(mock_instance)), []) + - with self.subTest("iterate through set return_value"): - mock_instance = MagicMock(self.WithAsyncIterator()) + def test_set_return_value(mock_type): + mock_instance = mock_type(self.WithAsyncIterator()) mock_instance.__aiter__.return_value = expected[:] - self.assertEqual(expected, asyncio.run(iterate(mock_instance))) + self.assertEqual(asyncio.run(iterate(mock_instance)), expected) - with self.subTest("iterate through set return_value iterator"): - mock_instance = MagicMock(self.WithAsyncIterator()) + def test_set_return_value_iter(mock_type): + mock_instance = mock_type(self.WithAsyncIterator()) mock_instance.__aiter__.return_value = iter(expected[:]) - self.assertEqual(expected, asyncio.run(iterate(mock_instance))) + self.assertEqual(asyncio.run(iterate(mock_instance)), expected) + + for mock_type in [AsyncMock, MagicMock]: + with self.subTest(f"default value with {mock_type}"): + test_default(mock_type) + + with self.subTest(f"set return_value with {mock_type}"): + test_set_return_value(mock_type) + + with self.subTest(f"set return_value iterator with {mock_type}"): + test_set_return_value_iter(mock_type) class AsyncMockAssert(unittest.TestCase): def setUp(self): self.mock = AsyncMock() - async def _runnable_test(self, *args): - if not args: - await self.mock() - else: - await self.mock(*args) + async def _runnable_test(self, *args, **kwargs): + await self.mock(*args, **kwargs) + + async def _await_coroutine(self, coroutine): + return await coroutine + + def test_assert_called_but_not_awaited(self): + mock = AsyncMock(AsyncClass) + with self.assertWarns(RuntimeWarning): + # Will raise a warning because never awaited + mock.async_method() + self.assertTrue(asyncio.iscoroutinefunction(mock.async_method)) + mock.async_method.assert_called() + mock.async_method.assert_called_once() + mock.async_method.assert_called_once_with() + with self.assertRaises(AssertionError): + mock.assert_awaited() + with self.assertRaises(AssertionError): + mock.async_method.assert_awaited() + + def test_assert_called_then_awaited(self): + mock = AsyncMock(AsyncClass) + mock_coroutine = mock.async_method() + mock.async_method.assert_called() + mock.async_method.assert_called_once() + mock.async_method.assert_called_once_with() + with self.assertRaises(AssertionError): + mock.async_method.assert_awaited() + + asyncio.run(self._await_coroutine(mock_coroutine)) + # Assert we haven't re-called the function + mock.async_method.assert_called_once() + mock.async_method.assert_awaited() + mock.async_method.assert_awaited_once() + mock.async_method.assert_awaited_once_with() + + def test_assert_called_and_awaited_at_same_time(self): + with self.assertRaises(AssertionError): + self.mock.assert_awaited() + + with self.assertRaises(AssertionError): + self.mock.assert_called() + + asyncio.run(self._runnable_test()) + self.mock.assert_called_once() + self.mock.assert_awaited_once() + + def test_assert_called_twice_and_awaited_once(self): + mock = AsyncMock(AsyncClass) + coroutine = mock.async_method() + with self.assertWarns(RuntimeWarning): + # The first call will be awaited so no warning there + # But this call will never get awaited, so it will warn here + mock.async_method() + with self.assertRaises(AssertionError): + mock.async_method.assert_awaited() + mock.async_method.assert_called() + asyncio.run(self._await_coroutine(coroutine)) + mock.async_method.assert_awaited() + mock.async_method.assert_awaited_once() + + def test_assert_called_once_and_awaited_twice(self): + mock = AsyncMock(AsyncClass) + coroutine = mock.async_method() + mock.async_method.assert_called_once() + asyncio.run(self._await_coroutine(coroutine)) + with self.assertRaises(RuntimeError): + # Cannot reuse already awaited coroutine + asyncio.run(self._await_coroutine(coroutine)) + mock.async_method.assert_awaited() + + def test_assert_awaited_but_not_called(self): + with self.assertRaises(AssertionError): + self.mock.assert_awaited() + with self.assertRaises(AssertionError): + self.mock.assert_called() + with self.assertRaises(TypeError): + # You cannot await an AsyncMock, it must be a coroutine + asyncio.run(self._await_coroutine(self.mock)) + + with self.assertRaises(AssertionError): + self.mock.assert_awaited() + with self.assertRaises(AssertionError): + self.mock.assert_called() + + def test_assert_has_calls_not_awaits(self): + kalls = [call('foo')] + with self.assertWarns(RuntimeWarning): + # Will raise a warning because never awaited + self.mock('foo') + self.mock.assert_has_calls(kalls) + with self.assertRaises(AssertionError): + self.mock.assert_has_awaits(kalls) + + def test_assert_has_mock_calls_on_async_mock_no_spec(self): + with self.assertWarns(RuntimeWarning): + # Will raise a warning because never awaited + self.mock() + kalls_empty = [('', (), {})] + self.assertEqual(self.mock.mock_calls, kalls_empty) + + with self.assertWarns(RuntimeWarning): + # Will raise a warning because never awaited + self.mock('foo') + self.mock('baz') + mock_kalls = ([call(), call('foo'), call('baz')]) + self.assertEqual(self.mock.mock_calls, mock_kalls) + + def test_assert_has_mock_calls_on_async_mock_with_spec(self): + a_class_mock = AsyncMock(AsyncClass) + with self.assertWarns(RuntimeWarning): + # Will raise a warning because never awaited + a_class_mock.async_method() + kalls_empty = [('', (), {})] + self.assertEqual(a_class_mock.async_method.mock_calls, kalls_empty) + self.assertEqual(a_class_mock.mock_calls, [call.async_method()]) + + with self.assertWarns(RuntimeWarning): + # Will raise a warning because never awaited + a_class_mock.async_method(1, 2, 3, a=4, b=5) + method_kalls = [call(), call(1, 2, 3, a=4, b=5)] + mock_kalls = [call.async_method(), call.async_method(1, 2, 3, a=4, b=5)] + self.assertEqual(a_class_mock.async_method.mock_calls, method_kalls) + self.assertEqual(a_class_mock.mock_calls, mock_kalls) + + def test_async_method_calls_recorded(self): + with self.assertWarns(RuntimeWarning): + # Will raise warnings because never awaited + self.mock.something(3, fish=None) + self.mock.something_else.something(6, cake=sentinel.Cake) + + self.assertEqual(self.mock.method_calls, [ + ("something", (3,), {'fish': None}), + ("something_else.something", (6,), {'cake': sentinel.Cake}) + ], + "method calls not recorded correctly") + self.assertEqual(self.mock.something_else.method_calls, + [("something", (6,), {'cake': sentinel.Cake})], + "method calls not recorded correctly") + + def test_async_arg_lists(self): + def assert_attrs(mock): + names = ('call_args_list', 'method_calls', 'mock_calls') + for name in names: + attr = getattr(mock, name) + self.assertIsInstance(attr, _CallList) + self.assertIsInstance(attr, list) + self.assertEqual(attr, []) + + assert_attrs(self.mock) + with self.assertWarns(RuntimeWarning): + # Will raise warnings because never awaited + self.mock() + self.mock(1, 2) + self.mock(a=3) + + self.mock.reset_mock() + assert_attrs(self.mock) + + a_mock = AsyncMock(AsyncClass) + with self.assertWarns(RuntimeWarning): + # Will raise warnings because never awaited + a_mock.async_method() + a_mock.async_method(1, a=3) + + a_mock.reset_mock() + assert_attrs(a_mock) def test_assert_awaited(self): with self.assertRaises(AssertionError): @@ -566,20 +837,20 @@ def test_assert_awaited_once_with(self): def test_assert_any_wait(self): with self.assertRaises(AssertionError): - self.mock.assert_any_await('NormalFoo') + self.mock.assert_any_await('foo') - asyncio.run(self._runnable_test('foo')) + asyncio.run(self._runnable_test('baz')) with self.assertRaises(AssertionError): - self.mock.assert_any_await('NormalFoo') + self.mock.assert_any_await('foo') - asyncio.run(self._runnable_test('NormalFoo')) - self.mock.assert_any_await('NormalFoo') + asyncio.run(self._runnable_test('foo')) + self.mock.assert_any_await('foo') asyncio.run(self._runnable_test('SomethingElse')) - self.mock.assert_any_await('NormalFoo') + self.mock.assert_any_await('foo') def test_assert_has_awaits_no_order(self): - calls = [call('NormalFoo'), call('baz')] + calls = [call('foo'), call('baz')] with self.assertRaises(AssertionError) as cm: self.mock.assert_has_awaits(calls) @@ -589,7 +860,7 @@ def test_assert_has_awaits_no_order(self): with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls) - asyncio.run(self._runnable_test('NormalFoo')) + asyncio.run(self._runnable_test('foo')) with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls) @@ -600,7 +871,7 @@ def test_assert_has_awaits_no_order(self): self.mock.assert_has_awaits(calls) def test_assert_has_awaits_ordered(self): - calls = [call('NormalFoo'), call('baz')] + calls = [call('foo'), call('baz')] with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls, any_order=True) @@ -608,11 +879,11 @@ def test_assert_has_awaits_ordered(self): with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls, any_order=True) - asyncio.run(self._runnable_test('foo')) + asyncio.run(self._runnable_test('bamf')) with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls, any_order=True) - asyncio.run(self._runnable_test('NormalFoo')) + asyncio.run(self._runnable_test('foo')) self.mock.assert_has_awaits(calls, any_order=True) asyncio.run(self._runnable_test('qux')) @@ -624,3 +895,30 @@ def test_assert_not_awaited(self): asyncio.run(self._runnable_test()) with self.assertRaises(AssertionError): self.mock.assert_not_awaited() + + def test_assert_has_awaits_not_matching_spec_error(self): + async def f(x=None): pass + + self.mock = AsyncMock(spec=f) + asyncio.run(self._runnable_test(1)) + + with self.assertRaisesRegex( + AssertionError, + '^{}$'.format( + re.escape('Awaits not found.\n' + 'Expected: [call()]\n' + 'Actual: [call(1)]'))) as cm: + self.mock.assert_has_awaits([call()]) + self.assertIsNone(cm.exception.__cause__) + + with self.assertRaisesRegex( + AssertionError, + '^{}$'.format( + re.escape( + 'Error processing expected awaits.\n' + "Errors: [None, TypeError('too many positional " + "arguments')]\n" + 'Expected: [call(), call(1, 2)]\n' + 'Actual: [call(1)]'))) as cm: + self.mock.assert_has_awaits([call(), call(1, 2)]) + self.assertIsInstance(cm.exception.__cause__, TypeError) diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/unittest/test/testmock/testhelpers.py index 301bca430c131c..f3c7acb98c21fa 100644 --- a/Lib/unittest/test/testmock/testhelpers.py +++ b/Lib/unittest/test/testmock/testhelpers.py @@ -334,6 +334,26 @@ def test_call_with_name(self): self.assertEqual(_Call((('bar', 'barz'),),)[0], '') self.assertEqual(_Call((('bar', 'barz'), {'hello': 'world'}),)[0], '') + def test_dunder_call(self): + m = MagicMock() + m().foo()['bar']() + self.assertEqual( + m.mock_calls, + [call(), call().foo(), call().foo().__getitem__('bar'), call().foo().__getitem__()()] + ) + m = MagicMock() + m().foo()['bar'] = 1 + self.assertEqual( + m.mock_calls, + [call(), call().foo(), call().foo().__setitem__('bar', 1)] + ) + m = MagicMock() + iter(m().foo()) + self.assertEqual( + m.mock_calls, + [call(), call().foo(), call().foo().__iter__()] + ) + class SpecSignatureTest(unittest.TestCase): diff --git a/Lib/unittest/test/testmock/testmagicmethods.py b/Lib/unittest/test/testmock/testmagicmethods.py index 130a3397ba0d8c..76b3a560de090a 100644 --- a/Lib/unittest/test/testmock/testmagicmethods.py +++ b/Lib/unittest/test/testmock/testmagicmethods.py @@ -1,8 +1,9 @@ +import asyncio import math import unittest import os import sys -from unittest.mock import Mock, MagicMock, _magics +from unittest.mock import AsyncMock, Mock, MagicMock, _magics @@ -270,6 +271,31 @@ def test_magic_mock_equality(self): self.assertEqual(mock == mock, True) self.assertEqual(mock != mock, False) + def test_asyncmock_defaults(self): + mock = AsyncMock() + self.assertEqual(int(mock), 1) + self.assertEqual(complex(mock), 1j) + self.assertEqual(float(mock), 1.0) + self.assertNotIn(object(), mock) + self.assertEqual(len(mock), 0) + self.assertEqual(list(mock), []) + self.assertEqual(hash(mock), object.__hash__(mock)) + self.assertEqual(str(mock), object.__str__(mock)) + self.assertTrue(bool(mock)) + self.assertEqual(round(mock), mock.__round__()) + self.assertEqual(math.trunc(mock), mock.__trunc__()) + self.assertEqual(math.floor(mock), mock.__floor__()) + self.assertEqual(math.ceil(mock), mock.__ceil__()) + self.assertTrue(asyncio.iscoroutinefunction(mock.__aexit__)) + self.assertTrue(asyncio.iscoroutinefunction(mock.__aenter__)) + self.assertIsInstance(mock.__aenter__, AsyncMock) + self.assertIsInstance(mock.__aexit__, AsyncMock) + + # in Python 3 oct and hex use __index__ + # so these tests are for __index__ in py3k + self.assertEqual(oct(mock), '0o1') + self.assertEqual(hex(mock), '0x1') + # how to test __sizeof__ ? def test_magicmock_defaults(self): mock = MagicMock() @@ -286,6 +312,10 @@ def test_magicmock_defaults(self): self.assertEqual(math.trunc(mock), mock.__trunc__()) self.assertEqual(math.floor(mock), mock.__floor__()) self.assertEqual(math.ceil(mock), mock.__ceil__()) + self.assertTrue(asyncio.iscoroutinefunction(mock.__aexit__)) + self.assertTrue(asyncio.iscoroutinefunction(mock.__aenter__)) + self.assertIsInstance(mock.__aenter__, AsyncMock) + self.assertIsInstance(mock.__aexit__, AsyncMock) # in Python 3 oct and hex use __index__ # so these tests are for __index__ in py3k diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py index 0f30bccc9cf0df..6dc2725427ec56 100644 --- a/Lib/unittest/test/testmock/testmock.py +++ b/Lib/unittest/test/testmock/testmock.py @@ -37,6 +37,9 @@ def cmeth(cls, a, b, c, d=None): pass def smeth(a, b, c, d=None): pass +def something(a): pass + + class MockTest(unittest.TestCase): def test_all(self): @@ -385,6 +388,14 @@ def _check(mock): _check(mock) + def test_assert_called_exception_message(self): + msg = "Expected '{0}' to have been called" + with self.assertRaisesRegex(AssertionError, msg.format('mock')): + Mock().assert_called() + with self.assertRaisesRegex(AssertionError, msg.format('test_name')): + Mock(name="test_name").assert_called() + + def test_assert_called_once_with(self): mock = Mock() mock() @@ -831,6 +842,7 @@ def test(): def test_setting_call(self): mock = Mock() def __call__(self, a): + self._increment_mock_call(a) return self._mock_call(a) type(mock).__call__ = __call__ @@ -1336,6 +1348,54 @@ def test_assert_has_calls(self): ) + def test_assert_has_calls_nested_spec(self): + class Something: + + def __init__(self): pass + def meth(self, a, b, c, d=None): pass + + class Foo: + + def __init__(self, a): pass + def meth1(self, a, b): pass + + mock_class = create_autospec(Something) + + for m in [mock_class, mock_class()]: + m.meth(1, 2, 3, d=1) + m.assert_has_calls([call.meth(1, 2, 3, d=1)]) + m.assert_has_calls([call.meth(1, 2, 3, 1)]) + + mock_class.reset_mock() + + for m in [mock_class, mock_class()]: + self.assertRaises(AssertionError, m.assert_has_calls, [call.Foo()]) + m.Foo(1).meth1(1, 2) + m.assert_has_calls([call.Foo(1), call.Foo(1).meth1(1, 2)]) + m.Foo.assert_has_calls([call(1), call().meth1(1, 2)]) + + mock_class.reset_mock() + + invalid_calls = [call.meth(1), + call.non_existent(1), + call.Foo().non_existent(1), + call.Foo().meth(1, 2, 3, 4)] + + for kall in invalid_calls: + self.assertRaises(AssertionError, + mock_class.assert_has_calls, + [kall] + ) + + + def test_assert_has_calls_nested_without_spec(self): + m = MagicMock() + m().foo().bar().baz() + m.one().two().three() + calls = call.one().two().three().call_list() + m.assert_has_calls(calls) + + def test_assert_has_calls_with_function_spec(self): def f(a, b, c, d=None): pass @@ -1367,6 +1427,32 @@ def f(a, b, c, d=None): pass mock.assert_has_calls(calls[:-1]) mock.assert_has_calls(calls[:-1], any_order=True) + def test_assert_has_calls_not_matching_spec_error(self): + def f(x=None): pass + + mock = Mock(spec=f) + mock(1) + + with self.assertRaisesRegex( + AssertionError, + '^{}$'.format( + re.escape('Calls not found.\n' + 'Expected: [call()]\n' + 'Actual: [call(1)]'))) as cm: + mock.assert_has_calls([call()]) + self.assertIsNone(cm.exception.__cause__) + + + with self.assertRaisesRegex( + AssertionError, + '^{}$'.format( + re.escape( + 'Error processing expected calls.\n' + "Errors: [None, TypeError('too many positional arguments')]\n" + "Expected: [call(), call(1, 2)]\n" + 'Actual: [call(1)]'))) as cm: + mock.assert_has_calls([call(), call(1, 2)]) + self.assertIsInstance(cm.exception.__cause__, TypeError) def test_assert_any_call(self): mock = Mock() @@ -1512,11 +1598,11 @@ def test_assert_called_once_message_not_called(self): m.assert_called_once() self.assertNotIn("Calls:", str(e.exception)) - #Issue21256 printout of keyword args should be in deterministic order - def test_sorted_call_signature(self): + #Issue37212 printout of keyword args now preserves the original order + def test_ordered_call_signature(self): m = Mock() m.hello(name='hello', daddy='hero') - text = "call(daddy='hero', name='hello')" + text = "call(name='hello', daddy='hero')" self.assertEqual(repr(m.hello.call_args), text) #Issue21270 overrides tuple methods for mock.call objects @@ -1808,6 +1894,26 @@ def test_attach_mock_return_value(self): self.assertEqual(m.mock_calls, call().foo().call_list()) + def test_attach_mock_patch_autospec(self): + parent = Mock() + + with mock.patch(f'{__name__}.something', autospec=True) as mock_func: + self.assertEqual(mock_func.mock._extract_mock_name(), 'something') + parent.attach_mock(mock_func, 'child') + parent.child(1) + something(2) + mock_func(3) + + parent_calls = [call.child(1), call.child(2), call.child(3)] + child_calls = [call(1), call(2), call(3)] + self.assertEqual(parent.mock_calls, parent_calls) + self.assertEqual(parent.child.mock_calls, child_calls) + self.assertEqual(something.mock_calls, child_calls) + self.assertEqual(mock_func.mock_calls, child_calls) + self.assertIn('mock.child', repr(parent.child.mock)) + self.assertEqual(mock_func.mock._extract_mock_name(), 'mock.child') + + def test_attribute_deletion(self): for mock in (Mock(), MagicMock(), NonCallableMagicMock(), NonCallableMock()): @@ -1891,6 +1997,20 @@ def foo(a, b): pass self.assertRaises(TypeError, mock.child, 1) self.assertEqual(mock.mock_calls, [call.child(1, 2)]) + self.assertIn('mock.child', repr(mock.child.mock)) + + def test_parent_propagation_with_autospec_attach_mock(self): + + def foo(a, b): pass + + parent = Mock() + parent.attach_mock(create_autospec(foo, name='bar'), 'child') + parent.child(1, 2) + + self.assertRaises(TypeError, parent.child, 1) + self.assertEqual(parent.child.mock_calls, [call.child(1, 2)]) + self.assertIn('mock.child', repr(parent.child.mock)) + def test_isinstance_under_settrace(self): # bpo-36593 : __class__ is not set for a class that has __class__ @@ -1924,7 +2044,7 @@ def trace(frame, event, arg): # pragma: no cover ) mocks = [ - Mock, MagicMock, NonCallableMock, NonCallableMagicMock + Mock, MagicMock, NonCallableMock, NonCallableMagicMock, AsyncMock ] for mock in mocks: diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/unittest/test/testmock/testpatch.py index 27914a9d71780a..0632d95e58fec0 100644 --- a/Lib/unittest/test/testmock/testpatch.py +++ b/Lib/unittest/test/testmock/testpatch.py @@ -1651,7 +1651,7 @@ def test_patch_imports_lazily(self): p1.stop() self.assertEqual(squizz.squozz, 3) - def test_patch_propogrates_exc_on_exit(self): + def test_patch_propagates_exc_on_exit(self): class holder: exc_info = None, None, None @@ -1680,9 +1680,9 @@ def test(mock): self.assertIs(holder.exc_info[0], RuntimeError) self.assertIsNotNone(holder.exc_info[1], - 'exception value not propgated') + 'exception value not propagated') self.assertIsNotNone(holder.exc_info[2], - 'exception traceback not propgated') + 'exception traceback not propagated') def test_create_and_specs(self): diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index b6608783a89471..d497925b943f44 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -431,31 +431,11 @@ def urlsplit(url, scheme='', allow_fragments=True): netloc = query = fragment = '' i = url.find(':') if i > 0: - if url[:i] == 'http': # optimize the common case - url = url[i+1:] - if url[:2] == '//': - netloc, url = _splitnetloc(url, 2) - if (('[' in netloc and ']' not in netloc) or - (']' in netloc and '[' not in netloc)): - raise ValueError("Invalid IPv6 URL") - if allow_fragments and '#' in url: - url, fragment = url.split('#', 1) - if '?' in url: - url, query = url.split('?', 1) - _checknetloc(netloc) - v = SplitResult('http', netloc, url, query, fragment) - _parse_cache[key] = v - return _coerce_result(v) for c in url[:i]: if c not in scheme_chars: break else: - # make sure "url" is not actually a port number (in which case - # "scheme" is really part of the path) - rest = url[i+1:] - if not rest or any(c not in '0123456789' for c in rest): - # not a port number - scheme, url = url[:i].lower(), rest + scheme, url = url[:i].lower(), url[i+1:] if url[:2] == '//': netloc, url = _splitnetloc(url, 2) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index f6ce9cb6d5866e..92c6a5d015051c 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -800,6 +800,7 @@ def __init__(self, proxies=None): assert hasattr(proxies, 'keys'), "proxies must be a mapping" self.proxies = proxies for type, url in proxies.items(): + type = type.lower() setattr(self, '%s_open' % type, lambda r, proxy=url, type=type, meth=self.proxy_open: meth(r, proxy, type)) diff --git a/Lib/urllib/robotparser.py b/Lib/urllib/robotparser.py index 7089916a4f81cc..c58565e3945146 100644 --- a/Lib/urllib/robotparser.py +++ b/Lib/urllib/robotparser.py @@ -186,7 +186,9 @@ def crawl_delay(self, useragent): for entry in self.entries: if entry.applies_to(useragent): return entry.delay - return self.default_entry.delay + if self.default_entry: + return self.default_entry.delay + return None def request_rate(self, useragent): if not self.mtime(): @@ -194,7 +196,9 @@ def request_rate(self, useragent): for entry in self.entries: if entry.applies_to(useragent): return entry.req_rate - return self.default_entry.req_rate + if self.default_entry: + return self.default_entry.req_rate + return None def site_maps(self): if not self.sitemaps: diff --git a/Lib/uuid.py b/Lib/uuid.py index ddc63ccd082c0b..188e16ba14e372 100644 --- a/Lib/uuid.py +++ b/Lib/uuid.py @@ -45,6 +45,7 @@ """ import os +import platform import sys from enum import Enum @@ -52,6 +53,12 @@ __author__ = 'Ka-Ping Yee ' +# The recognized platforms - known behaviors +_AIX = platform.system() == 'AIX' +_DARWIN = platform.system() == 'Darwin' +_LINUX = platform.system() == 'Linux' +_WINDOWS = platform.system() == 'Windows' + RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ 'reserved for NCS compatibility', 'specified in RFC 4122', 'reserved for Microsoft compatibility', 'reserved for future definition'] @@ -673,12 +680,31 @@ def _random_getnode(): return random.getrandbits(48) | (1 << 40) -_node = None - -_NODE_GETTERS_WIN32 = [_windll_getnode, _netbios_getnode, _ipconfig_getnode] +# _OS_GETTERS, when known, are targeted for a specific OS or platform. +# The order is by 'common practice' on the specified platform. +# Note: 'posix' and 'windows' _OS_GETTERS are prefixed by a dll/dlload() method +# which, when successful, means none of these "external" methods are called. +# _GETTERS is (also) used by test_uuid.py to SkipUnless(), e.g., +# @unittest.skipUnless(_uuid._ifconfig_getnode in _uuid._GETTERS, ...) +if _LINUX: + _OS_GETTERS = [_ip_getnode, _ifconfig_getnode] +elif _DARWIN: + _OS_GETTERS = [_ifconfig_getnode, _arp_getnode, _netstat_getnode] +elif _WINDOWS: + _OS_GETTERS = [_netbios_getnode, _ipconfig_getnode] +elif _AIX: + _OS_GETTERS = [_netstat_getnode] +else: + _OS_GETTERS = [_ifconfig_getnode, _ip_getnode, _arp_getnode, + _netstat_getnode, _lanscan_getnode] +if os.name == 'posix': + _GETTERS = [_unix_getnode] + _OS_GETTERS +elif os.name == 'nt': + _GETTERS = [_windll_getnode] + _OS_GETTERS +else: + _GETTERS = _OS_GETTERS -_NODE_GETTERS_UNIX = [_unix_getnode, _ifconfig_getnode, _ip_getnode, - _arp_getnode, _lanscan_getnode, _netstat_getnode] +_node = None def getnode(*, getters=None): """Get the hardware address as a 48-bit positive integer. @@ -692,12 +718,7 @@ def getnode(*, getters=None): if _node is not None: return _node - if sys.platform == 'win32': - getters = _NODE_GETTERS_WIN32 - else: - getters = _NODE_GETTERS_UNIX - - for getter in getters + [_random_getnode]: + for getter in _GETTERS + [_random_getnode]: try: _node = getter() except: diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index 4a49b240b8e217..caa7285b8c8979 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -105,8 +105,7 @@ def create_if_needed(d): prompt = self.prompt if self.prompt is not None else context.env_name context.prompt = '(%s) ' % prompt create_if_needed(env_dir) - env = os.environ - executable = getattr(sys, '_base_executable', sys.executable) + executable = sys._base_executable dirname, exename = os.path.split(os.path.abspath(executable)) context.executable = executable context.python_dir = dirname @@ -157,47 +156,66 @@ def create_configuration(self, context): if self.prompt is not None: f.write(f'prompt = {self.prompt!r}\n') - def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): - """ - Try symlinking a file, and if that fails, fall back to copying. - """ - force_copy = not self.symlinks - if not force_copy: - try: - if not os.path.islink(dst): # can't link to itself! + if os.name != 'nt': + def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): + """ + Try symlinking a file, and if that fails, fall back to copying. + """ + force_copy = not self.symlinks + if not force_copy: + try: + 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) + else: + os.symlink(src, dst) + except Exception: # may need to use a more specific exception + logger.warning('Unable to symlink %r to %r', src, dst) + force_copy = True + if force_copy: + shutil.copyfile(src, dst) + else: + def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): + """ + Try symlinking a file, and if that fails, fall back to copying. + """ + bad_src = os.path.lexists(src) and not os.path.exists(src) + if self.symlinks and not bad_src and not os.path.islink(dst): + try: if relative_symlinks_ok: assert os.path.dirname(src) == os.path.dirname(dst) os.symlink(os.path.basename(src), dst) else: os.symlink(src, dst) - except Exception: # may need to use a more specific exception - logger.warning('Unable to symlink %r to %r', src, dst) - force_copy = True - if force_copy: - if os.name == 'nt': - # On Windows, we rewrite symlinks to our base python.exe into - # copies of venvlauncher.exe - basename, ext = os.path.splitext(os.path.basename(src)) - srcfn = os.path.join(os.path.dirname(__file__), - "scripts", - "nt", - 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 basename.endswith('_d'): - ext = '_d' + ext - basename = basename[:-2] - if basename == 'python': - basename = 'venvlauncher' - elif basename == 'pythonw': - basename = 'venvwlauncher' - src = os.path.join(os.path.dirname(src), basename + ext) - else: - src = srcfn - if not os.path.exists(src): - logger.warning('Unable to copy %r', src) return + except Exception: # may need to use a more specific exception + logger.warning('Unable to symlink %r to %r', src, dst) + + # On Windows, we rewrite symlinks to our base python.exe into + # copies of venvlauncher.exe + basename, ext = os.path.splitext(os.path.basename(src)) + srcfn = os.path.join(os.path.dirname(__file__), + "scripts", + "nt", + 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 basename.endswith('_d'): + ext = '_d' + ext + basename = basename[:-2] + if basename == 'python': + basename = 'venvlauncher' + elif basename == 'pythonw': + basename = 'venvwlauncher' + src = os.path.join(os.path.dirname(src), basename + ext) + else: + src = srcfn + if not os.path.exists(src): + if not bad_src: + logger.warning('Unable to copy %r', src) + return shutil.copyfile(src, dst) @@ -245,7 +263,7 @@ def setup_python(self, context): for suffix in suffixes: src = os.path.join(dirname, suffix) - if os.path.exists(src): + if os.path.lexists(src): copier(src, os.path.join(binpath, suffix)) if sysconfig.is_python_build(True): diff --git a/Lib/venv/scripts/common/Activate.ps1 b/Lib/venv/scripts/common/Activate.ps1 index de22962630aabb..699c84097f1ac9 100644 --- a/Lib/venv/scripts/common/Activate.ps1 +++ b/Lib/venv/scripts/common/Activate.ps1 @@ -1,56 +1,231 @@ -function Script:add-bin([string]$envPath) { - $binPath = Join-Path -Path $env:VIRTUAL_ENV -ChildPath '__VENV_BIN_NAME__' - return ($binPath, $envPath) -join [IO.Path]::PathSeparator -} +<# +.Synopsis +Activate a Python virtual environment for the current Powershell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> function global:deactivate ([switch]$NonDestructive) { # Revert to original values - if (Test-Path function:_OLD_VIRTUAL_PROMPT) { - copy-item function:_OLD_VIRTUAL_PROMPT function:prompt - remove-item function:_OLD_VIRTUAL_PROMPT + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT } - if (Test-Path env:_OLD_VIRTUAL_PYTHONHOME) { - copy-item env:_OLD_VIRTUAL_PYTHONHOME env:PYTHONHOME - remove-item env:_OLD_VIRTUAL_PYTHONHOME + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME } - if (Test-Path env:_OLD_VIRTUAL_PATH) { - copy-item env:_OLD_VIRTUAL_PATH env:PATH - remove-item env:_OLD_VIRTUAL_PATH + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH } - if (Test-Path env:VIRTUAL_ENV) { - remove-item env:VIRTUAL_ENV + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0,1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } } + return $pyvenvConfig +} + - if (!$NonDestructive) { - # Self destruct! - remove-item function:deactivate +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + $VenvDir = $VenvDir.Insert($VenvDir.Length, "/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virutal environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf } } +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. deactivate -nondestructive -$env:VIRTUAL_ENV="__VENV_DIR__" +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" -if (! $env:VIRTUAL_ENV_DISABLE_PROMPT) { # Set the prompt to include the env name # Make sure _OLD_VIRTUAL_PROMPT is global - function global:_OLD_VIRTUAL_PROMPT {""} - copy-item function:prompt function:_OLD_VIRTUAL_PROMPT + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + function global:prompt { - Write-Host -NoNewline -ForegroundColor Green '__VENV_PROMPT__' + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " _OLD_VIRTUAL_PROMPT } } # Clear PYTHONHOME -if (Test-Path env:PYTHONHOME) { - copy-item env:PYTHONHOME env:_OLD_VIRTUAL_PYTHONHOME - remove-item env:PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME } # Add the venv to the PATH -copy-item env:PATH env:_OLD_VIRTUAL_PATH -$env:PATH = add-bin $env:PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/Lib/venv/scripts/common/activate b/Lib/venv/scripts/common/activate index fff0765af53b82..b9d498fb2ef04f 100644 --- a/Lib/venv/scripts/common/activate +++ b/Lib/venv/scripts/common/activate @@ -28,7 +28,7 @@ deactivate () { fi unset VIRTUAL_ENV - if [ ! "$1" = "nondestructive" ] ; then + if [ ! "${1:-}" = "nondestructive" ] ; then # Self destruct! unset -f deactivate fi diff --git a/Lib/venv/scripts/nt/activate.bat b/Lib/venv/scripts/nt/activate.bat index da831bb42c79b2..af4c7e0abacb1c 100644 --- a/Lib/venv/scripts/nt/activate.bat +++ b/Lib/venv/scripts/nt/activate.bat @@ -2,44 +2,32 @@ rem This file is UTF-8 encoded, so we need to update the current code page while executing it for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( - set "_OLD_CODEPAGE=%%a" + set _OLD_CODEPAGE=%%a ) if defined _OLD_CODEPAGE ( "%SystemRoot%\System32\chcp.com" 65001 > nul ) -set "VIRTUAL_ENV=__VENV_DIR__" +set VIRTUAL_ENV=__VENV_DIR__ -if not defined PROMPT ( - set "PROMPT=$P$G" -) - -if defined _OLD_VIRTUAL_PROMPT ( - set "PROMPT=%_OLD_VIRTUAL_PROMPT%" -) +if not defined PROMPT set PROMPT=$P$G -if defined _OLD_VIRTUAL_PYTHONHOME ( - set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" -) +if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% +if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% -set "_OLD_VIRTUAL_PROMPT=%PROMPT%" -set "PROMPT=__VENV_PROMPT__%PROMPT%" +set _OLD_VIRTUAL_PROMPT=%PROMPT% +set PROMPT=__VENV_PROMPT__%PROMPT% -if defined PYTHONHOME ( - set "_OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%" - set PYTHONHOME= -) +if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% +set PYTHONHOME= -if defined _OLD_VIRTUAL_PATH ( - set "PATH=%_OLD_VIRTUAL_PATH%" -) else ( - set "_OLD_VIRTUAL_PATH=%PATH%" -) +if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH% +if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH% -set "PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH%" +set PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH% :END if defined _OLD_CODEPAGE ( "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul - set "_OLD_CODEPAGE=" + set _OLD_CODEPAGE= ) diff --git a/Lib/weakref.py b/Lib/weakref.py index 8d71af653b7ec4..9d7008947f06d4 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -108,12 +108,12 @@ def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref): else: # Atomic removal is necessary since this function # can be called asynchronously by the GC - _atomic_removal(d, wr.key) + _atomic_removal(self.data, wr.key) self._remove = remove # A list of keys to be removed self._pending_removals = [] self._iterating = set() - self.data = d = {} + self.data = {} self.update(other, **kw) def _commit_removals(self): diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py index 82bff835fdd0be..0af36c4301d798 100755 --- a/Lib/webbrowser.py +++ b/Lib/webbrowser.py @@ -154,6 +154,7 @@ def __init__(self, name): self.basename = os.path.basename(self.name) def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) cmdline = [self.name] + [arg.replace("%s", url) for arg in self.args] try: @@ -173,6 +174,7 @@ class BackgroundBrowser(GenericBrowser): def open(self, url, new=0, autoraise=True): cmdline = [self.name] + [arg.replace("%s", url) for arg in self.args] + sys.audit("webbrowser.open", url) try: if sys.platform[:3] == 'win': p = subprocess.Popen(cmdline) @@ -201,7 +203,7 @@ class UnixBrowser(BaseBrowser): remote_action_newwin = None remote_action_newtab = None - def _invoke(self, args, remote, autoraise): + def _invoke(self, args, remote, autoraise, url=None): raise_opt = [] if remote and self.raise_opts: # use autoraise argument only for remote invocation @@ -237,6 +239,7 @@ def _invoke(self, args, remote, autoraise): return not p.wait() def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) if new == 0: action = self.remote_action elif new == 1: @@ -253,7 +256,7 @@ def open(self, url, new=0, autoraise=True): args = [arg.replace("%s", url).replace("%action", action) for arg in self.remote_args] args = [arg for arg in args if arg] - success = self._invoke(args, True, autoraise) + success = self._invoke(args, True, autoraise, url) if not success: # remote invocation failed, try straight way args = [arg.replace("%s", url) for arg in self.args] @@ -337,6 +340,7 @@ class Konqueror(BaseBrowser): """ def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) # XXX Currently I know no way to prevent KFM from opening a new win. if new == 2: action = "newTab" @@ -420,6 +424,7 @@ def _remote(self, action): return 1 def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) if new: ok = self._remote("LOADNEW " + url) else: @@ -577,6 +582,7 @@ def register_standard_browsers(): if sys.platform[:3] == "win": class WindowsDefault(BaseBrowser): def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) try: os.startfile(url) except OSError: @@ -606,6 +612,7 @@ def __init__(self, name): self.name = name def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) assert "'" not in url # hack for local urls if not ':' in url: diff --git a/Lib/xmlrpc/server.py b/Lib/xmlrpc/server.py index f1c467eb1b2b87..32aba4df4c7eb5 100644 --- a/Lib/xmlrpc/server.py +++ b/Lib/xmlrpc/server.py @@ -108,6 +108,7 @@ def export_add(self, x, y): from http.server import BaseHTTPRequestHandler from functools import partial from inspect import signature +import html import http.server import socketserver import sys @@ -894,7 +895,7 @@ def generate_html_documentation(self): methods ) - return documenter.page(self.server_title, documentation) + return documenter.page(html.escape(self.server_title), documentation) class DocXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): """XML-RPC and documentation request handler class. diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 62f2fd27d3ce6f..59435064eabf2b 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -7,6 +7,7 @@ import functools import importlib.util import io +import itertools import os import posixpath import shutil @@ -702,6 +703,7 @@ def _get_compressor(compress_type, compresslevel=None): def _get_decompressor(compress_type): + _check_compression(compress_type) if compress_type == ZIP_STORED: return None elif compress_type == ZIP_DEFLATED: @@ -2104,6 +2106,65 @@ def _compile(file, optimize=-1): return (fname, archivename) +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 itertools.filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element + + +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) + + class Path: """ A pathlib-compatible interface for zip files. @@ -2227,16 +2288,21 @@ def joinpath(self, add): __truediv__ = joinpath @staticmethod - def _add_implied_dirs(names): - return names + [ - name + "/" - for name in map(posixpath.dirname, names) - if name and name + "/" not in names - ] + def _implied_dirs(names): + return _unique_everseen( + parent + "/" + for name in names + for parent in _parents(name) + if parent + "/" not in names + ) + + @classmethod + def _add_implied_dirs(cls, names): + return names + list(cls._implied_dirs(names)) @property def parent(self): - parent_at = posixpath.dirname(self.at) + parent_at = posixpath.dirname(self.at.rstrip('/')) if parent_at: parent_at += '/' return self._next(parent_at) diff --git a/Mac/BuildScript/README.txt b/Mac/BuildScript/README.rst similarity index 100% rename from Mac/BuildScript/README.txt rename to Mac/BuildScript/README.rst diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 2c606b9df67452..0dd53647dd33e3 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -215,9 +215,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 1.1.0j", - url="https://www.openssl.org/source/openssl-1.1.0j.tar.gz", - checksum='b4ca5b78ae6ae79da80790b30dbedbdc', + name="OpenSSL 1.1.1d", + url="https://www.openssl.org/source/openssl-1.1.1d.tar.gz", + checksum='3be209000dbc7e1b95bcdf47980a3baa', buildrecipe=build_universal_openssl, configure=None, install=None, @@ -313,9 +313,9 @@ def library_recipes(): ), ), dict( - name="SQLite 3.22.0", - url="https://www.sqlite.org/2018/sqlite-autoconf-3220000.tar.gz", - checksum='96b5648d542e8afa6ab7ffb8db8ddc3d', + name="SQLite 3.28.0", + url="https://www.sqlite.org/2019/sqlite-autoconf-3280000.tar.gz", + checksum='3c68eb400f8354605736cd55400e1572', extra_cflags=('-Os ' '-DSQLITE_ENABLE_FTS5 ' '-DSQLITE_ENABLE_FTS4 ' @@ -810,6 +810,16 @@ def build_openssl_arch(archbase, arch): "ppc": ["darwin-ppc-cc"], "ppc64": ["darwin64-ppc-cc"], } + + # Somewhere between OpenSSL 1.1.0j and 1.1.1c, changes cause the + # "enable-ec_nistp_64_gcc_128" option to get compile errors when + # building on our 10.6 gcc-4.2 environment. There have been other + # reports of projects running into this when using older compilers. + # So, for now, do not try to use "enable-ec_nistp_64_gcc_128" when + # building for 10.6. + if getDeptargetTuple() == (10, 6): + arch_opts['x86_64'].remove('enable-ec_nistp_64_gcc_128') + configure_opts = [ "no-idea", "no-mdc2", diff --git a/Mac/BuildScript/resources/License.rtf b/Mac/BuildScript/resources/License.rtf index 20982a46cc36a9..7566cf3b44618a 100644 --- a/Mac/BuildScript/resources/License.rtf +++ b/Mac/BuildScript/resources/License.rtf @@ -1,29 +1,30 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1343\cocoasubrtf160 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fmodern\fcharset0 CourierNewPS-BoldMT;\f2\fmodern\fcharset0 CourierNewPSMT; -} +{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600 +{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;\f2\fmodern\fcharset0 CourierNewPS-BoldMT; +\f3\fmodern\fcharset0 CourierNewPSMT;} {\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} \margl1440\margr1440\vieww14620\viewh13380\viewkind0 -\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 \f0\b\fs36 \cf0 \ul \ulc0 HISTORY AND LICENSE\ \fs24 \ HISTORY OF THE SOFTWARE\ -\b0 \ulnone \ +\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.\ \ 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 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.com). In 2001, the Python Software Foundation (PSF, see http://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 http://www.zope.org). In 2001, the Python Software Foundation (PSF, see http://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.\ \ -\f1\b Release Derived Year Owner GPL-\ +\f2\b Release Derived Year Owner GPL-\ from compatible?\ -\f2\b0 \ +\f3\b0 \ 0.9.0 thru 1.2 n/a 1991-1995 CWI yes\ 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes\ 1.6 1.5.2 2000 CNRI no\ @@ -36,25 +37,25 @@ All Python releases are Open Source (see http://www.opensource.org for the Open 2.1.3 2.1.2 2002 PSF yes\ 2.2 and above 2.1.1 2001-now PSF yes\ -\f0 \ +\f1 \ -\b Note: -\b0 GPL-compatible doesn't mean that we're distributing Python under the GPL. All Python licenses, unlike the GPL, let you distribute a modified version without making your changes open source. The GPL-compatible licenses make it possible to combine Python with other software that is released under the GPL; the others don't.\ +\f0\b Note: +\f1\b0 GPL-compatible doesn't mean that we're distributing Python under the GPL. All Python licenses, unlike the GPL, let you distribute a modified version without making your changes open source. The GPL-compatible licenses make it possible to combine Python with other software that is released under the GPL; the others don't.\ \ Thanks to the many outside volunteers who have worked under Guido's direction to make these releases possible.\ \ \ -\b \ul TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON\ +\f0\b \ul TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON\ -\b0 \ulnone \ +\f1\b0 \ulnone \ -\b PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2\ +\f0\b PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2\ -\b0 \ +\f1\b0 \ 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation.\ \ -2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, 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 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee.\ +2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, 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 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee.\ \ 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python.\ \ @@ -70,9 +71,9 @@ Thanks to the many outside volunteers who have worked under Guido's direction to \ \ -\b BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0\ +\f0\b BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0\ -\b0 \ +\f1\b0 \ BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1\ \ 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization ("Licensee") accessing and otherwise using this software in source or binary form and its associated documentation ("the Software").\ @@ -91,9 +92,9 @@ BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1\ \ \ -\b CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1\ +\f0\b CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1\ -\b0 \ +\f1\b0 \ 1. This LICENSE AGREEMENT is between the Corporation for National Research Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191 ("CNRI"), and the Individual or Organization ("Licensee") accessing and otherwise using Python 1.6.1 software in source or binary form and its associated documentation.\ \ 2. Subject to the terms and conditions of this License Agreement, CNRI hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6.1 alone or in any derivative version, provided, however, that CNRI's License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) 1995-2001 Corporation for National Research Initiatives; All Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version prepared by Licensee. Alternately, in lieu of CNRI's License Agreement, Licensee may substitute the following text (omitting the quotes): "Python 1.6.1 is made available subject to the terms and conditions in CNRI's License Agreement. This Agreement together with Python 1.6.1 may be located on the Internet using the following unique, persistent identifier (known as a handle): 1895.22/1013. This Agreement may also be obtained from a proxy server on the Internet using the following URL: http://hdl.handle.net/1895.22/1013".\ @@ -114,9 +115,9 @@ BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1\ \ \ -\b CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2\ +\f0\b CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2\ -\b0 \ +\f1\b0 \ Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands. 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 Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.\ @@ -125,16 +126,16 @@ STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFT \ \ -\b \ul LICENSES AND ACKNOWLEDGEMENTS FOR INCORPORATED SOFTWARE\ +\f0\b \ul LICENSES AND ACKNOWLEDGEMENTS FOR INCORPORATED SOFTWARE\ -\b0 \ulnone \ +\f1\b0 \ulnone \ This installer incorporates portions of the following third-party software:\ \ -\f2 $THIRD_PARTY_LIBS\ +\f3 $THIRD_PARTY_LIBS\ \ -\f0 For licenses and acknowledgements for these and other third-party software incorporated in this Python distribution, please refer to the on-line documentation {\field{\*\fldinst{HYPERLINK "https://docs.python.org/$VERSION/license.html#licenses-and-acknowledgements-for-incorporated-software"}}{\fldrslt here}}.\ +\f1 For licenses and acknowledgements for these and other third-party software incorporated in this Python distribution, please refer to the on-line documentation {\field{\*\fldinst{HYPERLINK "https://docs.python.org/$VERSION/license.html#licenses-and-acknowledgements-for-incorporated-software"}}{\fldrslt here}}.\ \ \ \ diff --git a/Mac/BuildScript/resources/ReadMe.rtf b/Mac/BuildScript/resources/ReadMe.rtf index ab7aeff5376c2c..d321fcd80c2eb8 100644 --- a/Mac/BuildScript/resources/ReadMe.rtf +++ b/Mac/BuildScript/resources/ReadMe.rtf @@ -1,4 +1,4 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf200 +{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600 {\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fswiss\fcharset0 Helvetica-Oblique; \f3\fmodern\fcharset0 CourierNewPSMT;} {\colortbl;\red255\green255\blue255;} @@ -13,7 +13,7 @@ \f1\b \cf0 \ul \ulc0 Certificate verification and OpenSSL\ \f0\b0 \ulnone \ -This package includes its own private copy of OpenSSL 1.1.0. The trust certificates in system and user keychains managed by the +This package includes its own private copy of OpenSSL 1.1.1. The trust certificates in system and user keychains managed by the \f2\i Keychain Access \f0\i0 application and the \f2\i security @@ -23,21 +23,35 @@ This package includes its own private copy of OpenSSL 1.1.0. The trust certifi \f3 /Applications/Python 3.8 \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/}}). If you choose to use -\f3 certifi -\f0 , you should consider subscribing to the{\field{\*\fldinst{HYPERLINK "https://certifi.io/en/latest/"}}{\fldrslt project's email update service}} to be notified when the certificate bundle is updated.\ +\f0 package ({\field{\*\fldinst{HYPERLINK "https://pypi.org/project/certifi/"}}{\fldrslt https://pypi.org/project/certifi/}}). Double-click on +\f3 Install Certificates +\f0 to run it.\ \ The bundled \f3 pip -\f0 included with this installer has its own default certificate store for verifying download connections.\ +\f0 has its own default certificate store for verifying download connections.\ \ \f1\b \ul Using IDLE or other Tk applications \f0\b0 \ulnone \ \ This package includes its own private version of Tcl/Tk 8.6. It does not use any system-supplied or third-party supplied versions of Tcl/Tk.\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 +\cf0 \ +Due to new security checks on macOS 10.15 Catalina, when launching IDLE macOS may open a window with a message +\f1\b "Python" would like to access files in your Documents folder +\f0\b0 . This is normal as IDLE uses your +\f1\b Documents +\f0\b0 folder as its default when opening and saving files; you can still choose other locations in the +\f1\b Open +\f0\b0 and +\f1\b Save +\f0\b0 file dialog windows. Click on the +\f1\b OK +\f0\b0 button to proceed.\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 -\f1\b \ul \ +\f1\b \cf0 \ul \ulc0 \ Other changes\ \f0\b0 \ulnone \ @@ -46,34 +60,4 @@ For other changes in this release, see the \f0\i0 section in the {\field{\*\fldinst{HYPERLINK "https://www.python.org/doc/"}}{\fldrslt Documentation Set}} for this release and its \f2\i Release Notes \f0\i0 link at {\field{\*\fldinst{HYPERLINK "https://www.python.org/downloads/"}}{\fldrslt https://www.python.org/downloads/}}.\ - -\f1\b \ul \ -Python 3 and Python 2 Co-existence\ - -\f0\b0 \ulnone \ -Python.org Python $VERSION and 2.7.x versions can both be installed on your system and will not conflict. Command names for Python 3 contain a 3 in them, -\f3 python3 -\f0 (or -\f3 python$VERSION -\f0 ), -\f3 idle3 -\f0 (or i -\f3 dle$VERSION -\f0 ), -\f3 pip3 -\f0 (or -\f3 pip$VERSION -\f0 ), etc. Python 2.7 command names contain a 2 or no digit: -\f3 python2 -\f0 (or -\f3 python2.7 -\f0 or -\f3 python -\f0 ), -\f3 idle2 -\f0 (or -\f3 idle2.7 -\f0 or -\f3 idle -\f0 ), etc.\ } \ No newline at end of file diff --git a/Mac/BuildScript/resources/Welcome.rtf b/Mac/BuildScript/resources/Welcome.rtf index df5d20da9ebb00..ce53bd78bbd46a 100644 --- a/Mac/BuildScript/resources/Welcome.rtf +++ b/Mac/BuildScript/resources/Welcome.rtf @@ -1,5 +1,6 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;} +{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fmodern\fcharset0 CourierNewPSMT; +} {\colortbl;\red255\green255\blue255;} {\*\expandedcolortbl;;} \paperw11905\paperh16837\margl1440\margr1440\vieww12200\viewh10880\viewkind0 @@ -13,11 +14,13 @@ \ \f1\b Python for macOS -\f0\b0 consists of the Python programming language interpreter, plus a set of programs to allow easy access to it for macOS users including an integrated development environment +\f0\b0 consists of the {\field{\*\fldinst{HYPERLINK "https://www.python.org"}}{\fldrslt Python}} programming language interpreter and its batteries-included standard library to allow easy access to macOS features. It also includes the Python integrated development environment, \f1\b IDLE -\f0\b0 .\ +\f0\b0 . You can also use the included +\f1\b pip +\f0\b0 to download and install third-party packages from the {\field{\*\fldinst{HYPERLINK "https://pypi.org"}}{\fldrslt Python Package Index}}. \ \ - -\f1\b NOTE: -\f0\b0 This is an alpha test preview of Python 3.8.0, the next feature release of Python 3.8. It is not intended for production use.\ +At the end of this install, click on +\f2 Install Certificates +\f0 to install a set of current SSL root certificates.\ } \ No newline at end of file diff --git a/Mac/README b/Mac/README.rst similarity index 74% rename from Mac/README rename to Mac/README.rst index d4194747ebb05c..4f2e2ce6623df7 100644 --- a/Mac/README +++ b/Mac/README.rst @@ -1,25 +1,23 @@ -========================= -Python on Mac OS X README -========================= +====================== +Python on macOS README +====================== :Authors: Jack Jansen (2004-07), Ronald Oussoren (2010-04), Ned Deily (2012-06) -:Version: 3.4.0 - -This document provides a quick overview of some Mac OS X specific features in +This document provides a quick overview of some macOS specific features in the Python distribution. -OS X specific arguments to configure -==================================== +macOS specific arguments to configure +===================================== * ``--enable-framework[=DIR]`` If this argument is specified the build will create a Python.framework rather than a traditional Unix install. See the section - _`Building and using a framework-based Python on Mac OS X` for more + _`Building and using a framework-based Python on macOS` for more information on frameworks. If the optional directory argument is specified the framework is installed @@ -43,41 +41,51 @@ OS X specific arguments to configure Create a universal binary build of Python. This can be used with both regular and framework builds. - The optional argument specifies which OS X SDK should be used to perform the - build. If xcodebuild is available and configured, this defaults to - the Xcode default MacOS X SDK, otherwise ``/Developer/SDKs/MacOSX.10.4u.sdk`` - if available or ``/`` if not. When building on OS X 10.5 or later, you can - specify ``/`` to use the installed system headers rather than an SDK. As of - OS X 10.9, you should install the optional system headers from the Command - Line Tools component using ``xcode-select``:: - - $ sudo xcode-select --install - - See the section _`Building and using a universal binary of Python on Mac OS X` - for more information. + The optional argument specifies which macOS SDK should be used to perform the + build. In most cases on current systems, you do not need to specify PATH or + you can just use ``/``; the default MacOSX SDK for the active Xcode or Command + Line Tools developer directory will be used. See the macOS ``xcrun`` man page + for more information. Current versions of macOS and Xcode no longer install + system header files in their traditional locations, like ``/usr/include`` and + ``/System/Library/Frameworks``; instead they are found within a MacOSX SDK. + The Apple-supplied build tools handle this transparently and current + versiona of Python now handle this as well. So it is no longer necessary, + and since macOS 10.14, no longer possible to force the installation of system + headers with ``xcode-select``. * ``--with-universal-archs=VALUE`` Specify the kind of universal binary that should be created. This option is only valid when ``--enable-universalsdk`` is specified. The default is - ``32-bit`` if a building with a SDK that supports PPC, otherwise defaults - to ``intel``. + ``32-bit`` if building with a SDK that supports PPC, otherwise defaults + to ``intel``. Note that ``intel`` means a universal build of both 32-bit + and 64-bit binaries and that may not be what you want; for example, + as of macOS 10.15 Catalina, 32-bit execution is no longer supported by + the operating system. Thus it is best to either explicitly specify + values for ``--with-universal-archs``: + ``--enable-universalsdk --with-universal-archs=intel-64`` -Building and using a universal binary of Python on Mac OS X -=========================================================== + or avoid using either. + + +Building and using a universal binary of Python on macOS +======================================================== 1. What is a universal binary ----------------------------- A universal binary build of Python contains object code for more than one -CPU architecture. A universal OS X executable file or library combines the +CPU architecture. A universal macOS executable file or library combines the architecture-specific code into one file and can therefore run at native speed on all supported architectures. Universal files were introduced in -OS X 10.4 to add support for Intel-based Macs to the existing PowerPC (PPC) -machines. In OS X 10.5 support was extended to 64-bit Intel and 64-bit PPC +macOS 10.4 to add support for Intel-based Macs to the existing PowerPC (PPC) +machines. In macOS 10.5 support was extended to 64-bit Intel and 64-bit PPC architectures. It is possible to build Python with various combinations -of architectures depending on the build tools and OS X version in use. +of architectures depending on the build tools and macOS version in use. +Note that PPC support was removed in macOS 10.7 and 32-bit Intel support +was removed in macOS 10.15. So currently as of macOS 10.15, macOS only +supports one execution architecture, 64-bit Intel (``x86_64``). 2. How do I build a universal binary ------------------------------------ @@ -90,14 +98,14 @@ flag to configure:: $ make install This flag can be used with a framework build of python, but also with a classic -unix build. Universal builds were first supported with OS X 10.4 with Xcode 2.1 -and the 10.4u SDK. Starting with Xcode 3 and OS X 10.5, more configurations are +unix build. Universal builds were first supported with macOS 10.4 with Xcode 2.1 +and the 10.4u SDK. Starting with Xcode 3 and macOS 10.5, more configurations are available. In general, universal builds depend on specific features provided by the Apple-supplied compilers and other build tools included in Apple's Xcode -development tools. You should install Xcode and the command line tools -component appropriate for the OS X release you are running on. See the +development tools. You should install Xcode or the command line tools +component appropriate for the macOS release you are running on. See the Python Developer's Guide (https://devguide.python.org/setup/) for more information. @@ -116,6 +124,8 @@ values are available: * ``intel-32``: ``i386`` + * ``intel-64``: ``x86_64`` + * ``32-bit``: ``ppc``, ``i386`` * ``3-way``: ``i386``, ``x86_64``, ``ppc`` @@ -125,28 +135,29 @@ values are available: * ``all``: ``ppc``, ``ppc64``, ``i386``, ``x86_64`` To build a universal binary that includes a 64-bit architecture, you must build -on a system running OS X 10.5 or later. The ``all`` and ``64-bit`` flavors can +on a system running macOS 10.5 or later. The ``all`` and ``64-bit`` flavors can only be built with a 10.5 SDK because ``ppc64`` support was only included with -OS X 10.5. Although legacy ``ppc`` support was included with Xcode 3 on OS X -10.6, it was removed in Xcode 4, versions of which were released on OS X 10.6 -and which is the standard for OS X 10.7. To summarize, the +macOS 10.5. Although legacy ``ppc`` support was included with Xcode 3 on macOS +10.6, it was removed in Xcode 4, versions of which were released on macOS 10.6 +and which is the standard for macOS 10.7. To summarize, the following combinations of SDKs and universal-archs flavors are available: * 10.4u SDK with Xcode 2 supports ``32-bit`` only * 10.5 SDK with Xcode 3.1.x supports all flavors - * 10.6 SDK with Xcode 3.2.x supports ``intel``, ``3-way``, and ``32-bit`` + * 10.6 SDK with Xcode 3.2.x supports ``intel``, ``intel-32``, + ``intel-64``, ``3-way``, and ``32-bit`` - * 10.6 SDK with Xcode 4 supports ``intel`` only + * 10.6 SDK with Xcode 4 supports ``intel``, ``intel-32``, and ``intel-64`` - * 10.7 and 10.8 SDKs with Xcode 4 support ``intel`` only + * 10.7 through 10.14 SDKs support ``intel``, ``intel-32``, and ``intel-64`` - * 10.8 and 10.9 SDKs with Xcode 5 support ``intel`` only + * 10.15 and later SDKs support ``intel-64`` only -The makefile for a framework build will also install ``python3.4-32`` +The makefile for a framework build will also install ``python3.x-32`` binaries when the universal architecture includes at least one 32-bit -architecture (that is, for all flavors but ``64-bit``). +architecture (that is, for all flavors but ``64-bit`` and ``intel-64``). Running a specific architecture ............................... @@ -159,20 +170,15 @@ Or to explicitly run in 32-bit mode, regardless of the machine hardware:: $ arch -i386 -ppc python -NOTE: When you're using a framework install of Python this requires at least -Python 2.7 or 3.2, in earlier versions the python (and pythonw) commands are -wrapper tools that execute the real interpreter without ensuring that the -real interpreter runs with the same architecture. - Using ``arch`` is not a perfect solution as the selected architecture will not automatically carry through to subprocesses launched by programs and tests under that Python. If you want to ensure that Python interpreters launched in subprocesses also run in 32-bit-mode if the main interpreter does, use -a ``python3.4-32`` binary and use the value of ``sys.executable`` as the +a ``python3.x-32`` binary and use the value of ``sys.executable`` as the ``subprocess`` ``Popen`` executable value. -Building and using a framework-based Python on Mac OS X. -======================================================== +Building and using a framework-based Python on macOS +==================================================== 1. Why would I want a framework Python instead of a normal static Python? @@ -180,18 +186,18 @@ Building and using a framework-based Python on Mac OS X. The main reason is because you want to create GUI programs in Python. With the exception of X11/XDarwin-based GUI toolkits all GUI programs need to be run -from a Mac OS X application bundle (".app"). +from a macOS application bundle (".app"). While it is technically possible to create a .app without using frameworks you will have to do the work yourself if you really want this. A second reason for using frameworks is that they put Python-related items in only two places: "/Library/Framework/Python.framework" and -"/Applications/Python " where ```` can be e.g. "3.4", +"/Applications/Python " where ```` can be e.g. "3.8", "2.7", etc. This simplifies matters for users installing Python from a binary distribution if they want to get rid of it again. Moreover, -due to the way frameworks work, a user without admin privileges can install a -binary distribution in his or her home directory without recompilation. +due to the way frameworks work, usera without admin privileges can install a +binary distribution in their home directory without recompilation. 2. How does a framework Python differ from a normal static Python? ------------------------------------------------------------------ @@ -205,12 +211,12 @@ Versions/Current and you will see the familiar bin and lib directories. 3. Do I need extra packages? ---------------------------- -Yes, probably. If you want Tkinter support you need to get the OS X AquaTk -distribution, this is installed by default on Mac OS X 10.4 or later. Be -aware, though, that the Cocoa-based AquaTk's supplied starting with OS X +Yes, probably. If you want Tkinter support you need to get the macOS AquaTk +distribution, this is installed by default on macOS 10.4 or later. Be +aware, though, that the Cocoa-based AquaTk's supplied starting with macOS 10.6 have proven to be unstable. If possible, you should consider -installing a newer version before building on OS X 10.6 or later, such as -the ActiveTcl 8.5. See http://www.python.org/download/mac/tcltk/. If you +installing a newer version before building on macOS 10.6 or later, such as +the ActiveTcl 8.6. See http://www.python.org/download/mac/tcltk/. If you are building with an SDK, ensure that the newer Tcl and Tk frameworks are seen in the SDK's ``Library/Frameworks`` directory; you may need to manually create symlinks to their installed location, ``/Library/Frameworks``. @@ -221,7 +227,7 @@ If you want Cocoa you need to get PyObjC. ------------------------------------- This directory contains a Makefile that will create a couple of python-related -applications (full-blown OS X .app applications, that is) in +applications (full-blown macOS .app applications, that is) in "/Applications/Python ", and a hidden helper application Python.app inside the Python.framework, and unix tools including "python" into /usr/local/bin. In addition it has a target "installmacsubtree" that installs @@ -271,7 +277,7 @@ through Python Launcher's preferences dialog. The program ``pythonx.x`` runs python scripts from the command line. Previously, various compatibility aliases were also installed, including -``pythonwx.x`` which in early releases of Python on OS X was required to run +``pythonwx.x`` which in early releases of Python on macOS was required to run GUI programs. As of 3.4.0, the ``pythonwx.x`` aliases are no longer installed. How do I create a binary distribution? @@ -288,18 +294,17 @@ installer package will create links to the documentation for use by IDLE, pydoc, shell users, and Finder user. The script will build a universal binary so you'll therefore have to run this -script on Mac OS X 10.4 or later and with Xcode 2.1 or later installed. +script on macOS 10.4 or later and with Xcode 2.1 or later installed. However, the Python build process itself has several build dependencies not -available out of the box with OS X 10.4 so you may have to install -additional software beyond what is provided with Xcode 2. OS X 10.5 -provides a recent enough system Python (in ``/usr/bin``) to build -the Python documentation set. It should be possible to use SDKs and/or older +available out of the box with macOS 10.4 so you may have to install +additional software beyond what is provided with Xcode 2. +It should be possible to use SDKs and/or older versions of Xcode to build installers that are compatible with older systems on a newer system but this may not be completely foolproof so the resulting executables, shared libraries, and ``.so`` bundles should be carefully examined and tested on all supported systems for proper dynamic linking dependencies. It is safest to build the distribution on a system running the -minimum OS X version supported. +minimum macOS version supported. All of this is normally done completely isolated in /tmp/_py, so it does not use your normal build directory nor does it install into /. @@ -333,7 +338,7 @@ Uninstalling a framework install, including the binary installer Uninstalling a framework can be done by manually removing all bits that got installed. That's true for both installations from source and installations using the binary installer. -OS X does not provide a central uninstaller. +macOS does not provide a central uninstaller. The main bit of a framework install is the framework itself, installed in ``/Library/Frameworks/Python.framework``. This can contain multiple versions diff --git a/Makefile.pre.in b/Makefile.pre.in index a0bc9c1f1cc897..502317aa0c783a 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -255,9 +255,10 @@ TCLTK_INCLUDES= @TCLTK_INCLUDES@ TCLTK_LIBS= @TCLTK_LIBS@ # The task to run while instrumented when building the profile-opt target. -# We exclude unittests with -x that take a rediculious amount of time to -# run in the instrumented training build or do not provide much value. -PROFILE_TASK=-m test.regrtest --pgo +# 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 +# PROFILE_TASK="-m test --pgo-extended" +PROFILE_TASK= @PROFILE_TASK@ # report files for gcov / lcov coverage report COVERAGE_INFO= $(abs_builddir)/coverage.info @@ -304,8 +305,9 @@ POBJS= \ PARSER_OBJS= $(POBJS) Parser/myreadline.o Parser/parsetok.o Parser/tokenizer.o PARSER_HEADERS= \ - $(srcdir)/Parser/parser.h \ + $(srcdir)/Include/grammar.h \ $(srcdir)/Include/parsetok.h \ + $(srcdir)/Parser/parser.h \ $(srcdir)/Parser/tokenizer.h ########################################################################## @@ -438,7 +440,7 @@ LIBRARY_OBJS= \ # On some systems, object files that reference DTrace probes need to be modified # in-place by dtrace(1). DTRACE_DEPS = \ - Python/ceval.o Python/import.o Modules/gcmodule.o + Python/ceval.o Python/import.o Python/sysmodule.o Modules/gcmodule.o ######################################################################### # Rules @@ -780,7 +782,7 @@ Python/dynload_hpux.o: $(srcdir)/Python/dynload_hpux.c Makefile -DSHLIB_EXT='"$(EXT_SUFFIX)"' \ -o $@ $(srcdir)/Python/dynload_hpux.c -Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile +Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(srcdir)/Include/pydtrace.h $(CC) -c $(PY_CORE_CFLAGS) \ -DABIFLAGS='"$(ABIFLAGS)"' \ $(MULTIARCH_CPPFLAGS) \ @@ -864,7 +866,7 @@ regen-symbol: $(srcdir)/Include/graminit.h $(srcdir)/Include/graminit.h \ $(srcdir)/Lib/symbol.py -Python/compile.o Python/symtable.o Python/ast_unparse.o Python/ast.o: $(srcdir)/Include/graminit.h $(srcdir)/Include/Python-ast.h +Python/compile.o Python/symtable.o Python/ast_unparse.o Python/ast.o Python/future.o Parser/parsetok.o: $(srcdir)/Include/graminit.h $(srcdir)/Include/Python-ast.h Python/getplatform.o: $(srcdir)/Python/getplatform.c $(CC) -c $(PY_CORE_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c @@ -938,9 +940,9 @@ Include/pydtrace_probes.h: $(srcdir)/Include/pydtrace.d sed 's/PYTHON_/PyDTrace_/' $@ > $@.tmp mv $@.tmp $@ -Python/ceval.o: Include/pydtrace.h -Python/import.o: Include/pydtrace.h -Modules/gcmodule.o: Include/pydtrace.h +Python/ceval.o: $(srcdir)/Include/pydtrace.h +Python/import.o: $(srcdir)/Include/pydtrace.h +Modules/gcmodule.o: $(srcdir)/Include/pydtrace.h Python/pydtrace.o: $(srcdir)/Include/pydtrace.d $(DTRACE_DEPS) $(DTRACE) $(DFLAGS) -o $@ -G -s $< $(DTRACE_DEPS) @@ -964,11 +966,11 @@ PYTHON_HEADERS= \ $(srcdir)/Include/abstract.h \ $(srcdir)/Include/asdl.h \ $(srcdir)/Include/ast.h \ - $(srcdir)/Include/bltinmodule.h \ $(srcdir)/Include/bitset.h \ + $(srcdir)/Include/bltinmodule.h \ $(srcdir)/Include/boolobject.h \ - $(srcdir)/Include/bytes_methods.h \ $(srcdir)/Include/bytearrayobject.h \ + $(srcdir)/Include/bytes_methods.h \ $(srcdir)/Include/bytesobject.h \ $(srcdir)/Include/cellobject.h \ $(srcdir)/Include/ceval.h \ @@ -977,6 +979,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/codecs.h \ $(srcdir)/Include/compile.h \ $(srcdir)/Include/complexobject.h \ + $(srcdir)/Include/context.h \ $(srcdir)/Include/descrobject.h \ $(srcdir)/Include/dictobject.h \ $(srcdir)/Include/dtoa.h \ @@ -1006,6 +1009,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/node.h \ $(srcdir)/Include/object.h \ $(srcdir)/Include/objimpl.h \ + $(srcdir)/Include/odictobject.h \ $(srcdir)/Include/opcode.h \ $(srcdir)/Include/osdefs.h \ $(srcdir)/Include/osmodule.h \ @@ -1020,15 +1024,15 @@ PYTHON_HEADERS= \ $(srcdir)/Include/pyfpe.h \ $(srcdir)/Include/pyhash.h \ $(srcdir)/Include/pylifecycle.h \ - $(srcdir)/Include/pymath.h \ + $(srcdir)/Include/pymacconfig.h \ $(srcdir)/Include/pymacro.h \ + $(srcdir)/Include/pymath.h \ $(srcdir)/Include/pymem.h \ $(srcdir)/Include/pyport.h \ $(srcdir)/Include/pystate.h \ - $(srcdir)/Include/context.h \ $(srcdir)/Include/pystrcmp.h \ - $(srcdir)/Include/pystrtod.h \ $(srcdir)/Include/pystrhex.h \ + $(srcdir)/Include/pystrtod.h \ $(srcdir)/Include/pythonrun.h \ $(srcdir)/Include/pythread.h \ $(srcdir)/Include/pytime.h \ @@ -1039,6 +1043,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/structseq.h \ $(srcdir)/Include/symtable.h \ $(srcdir)/Include/sysmodule.h \ + $(srcdir)/Include/token.h \ $(srcdir)/Include/traceback.h \ $(srcdir)/Include/tracemalloc.h \ $(srcdir)/Include/tupleobject.h \ @@ -1102,6 +1107,11 @@ TESTTIMEOUT= 1200 .PHONY: test testall testuniversal buildbottest pythoninfo +# Remove "test_python_*" directories of previous failed test jobs. +# Pass TESTOPTS options because it can contain --tempdir option. +cleantest: build_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 @@ -1362,6 +1372,7 @@ LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \ test/test_importlib/source \ test/test_importlib/zipdata01 \ test/test_importlib/zipdata02 \ + test/ziptestdata \ asyncio \ test/test_asyncio \ collections concurrent concurrent/futures encodings \ diff --git a/Misc/ACKS b/Misc/ACKS index 082fa567f23aa6..406009c4e2016d 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -58,6 +58,7 @@ Jon Anglin Michele Angrisano Ankur Ankan Heidi Annexstad +David Antonini Ramchandra Apte Éric Araujo Alexandru Ardelean @@ -162,6 +163,7 @@ Roy Bixler Daniel Black Jonathan Black Renaud Blanch +Justin Blanchard Mike Bland Martin Bless Pablo Bleyer @@ -178,6 +180,7 @@ Nikolay Bogoychev David Bolen Wouter Bolsterlee Gawain Bolton +Carl Friedrich Bolz-Tereick Forest Bond Gregory Bond Médéric Boquien @@ -394,6 +397,7 @@ Alon Diamant Toby Dickenson Mark Dickinson Jack Diederich +Karl Ding Daniel Diniz Humberto Diogenes Yves Dionne @@ -411,6 +415,7 @@ Dima Dorfman Yves Dorfsman Michael Dorman Steve Dower +Allen Downey Cesar Douady Dean Draayer Fred L. Drake, Jr. @@ -507,6 +512,7 @@ Arnaud Fontaine Michael Foord Amaury Forgeot d'Arc Doug Fort +Daniel Fortunov Evens Fortuné Chris Foster John Fouhy @@ -640,6 +646,7 @@ Travis B. Hartwell Shane Harvey Larry Hastings Tim Hatch +Zac Hatfield-Dodds Shane Hathaway Michael Haubenwallner Janko Hauser @@ -829,6 +836,7 @@ Lawrence Kesteloot Garvit Khatri Vivek Khera Dhiru Kholia +Artem Khramov Akshit Khurana Sanyam Khurana Mads Kiilerich @@ -962,6 +970,7 @@ Alain Leufroy Mark Levinson Mark Levitt Ivan Levkivskyi +Ben Lewis William Lewis Akira Li Robert Li @@ -1324,6 +1333,7 @@ Burton Radons Abhilash Raj Shorya Raj Dhushyanth Ramasamy +Ashwin Ramaswami Jeff Ramnani Bayard Randel Varpu Rantala @@ -1531,6 +1541,7 @@ Ng Pheng Siong Yann Sionneau George Sipe J. Sipprell +Ngalim Siregar Kragen Sitaker Kaartic Sivaraam Ville Skyttä @@ -1607,6 +1618,7 @@ Kalle Svensson Andrew Svetlov Paul Swartz Al Sweigart +Sviatoslav Sydorenko Thenault Sylvain Péter Szabó John Szakmeister @@ -1697,6 +1709,7 @@ Michael Urman Hector Urtubia Lukas Vacek Ville Vainio +Yann Vaginay Andi Vajda Case Van Horsen John Mark Vandenberg @@ -1853,6 +1866,7 @@ Nickolai Zeldovich Yuxiao Zeng Uwe Zessin Cheng Zhang +George Zhang Kai Zhu Tarek Ziadé Jelle Zijlstra @@ -1865,3 +1879,6 @@ Diego Rojas Edison Abahurire Geoff Shannon Batuhan Taskaya +Aleksandr Balezin +Robert Leenders +Ngalim Siregar diff --git a/Misc/HISTORY b/Misc/HISTORY index f4b756cf0a463b..fa5a05fd40fd3a 100644 --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -1231,7 +1231,7 @@ Library - Issue #22448: Improve canceled timer handles cleanup to prevent unbound memory usage. Patch by Joshua Moore-Oliva. -- Issue #23009: Make sure selectors.EpollSelecrtor.select() works when no +- Issue #23009: Make sure selectors.EpollSelector.select() works when no FD is registered. IDLE @@ -16660,7 +16660,7 @@ Core and Builtins Exception (KeyboardInterrupt, and SystemExit) propagate instead of ignoring them. -- #3021 Exception reraising sematics have been significantly improved. However, +- #3021 Exception reraising semantics have been significantly improved. However, f_exc_type, f_exc_value, and f_exc_traceback cannot be accessed from Python code anymore. diff --git a/Misc/NEWS.d/3.5.0a1.rst b/Misc/NEWS.d/3.5.0a1.rst index 62406e1aa00866..376cb02ed4ba3d 100644 --- a/Misc/NEWS.d/3.5.0a1.rst +++ b/Misc/NEWS.d/3.5.0a1.rst @@ -1255,7 +1255,7 @@ Support wrapped callables in doctest. Patch by Claudiu Popa. .. nonce: -sW7gk .. section: Library -Make sure selectors.EpollSelecrtor.select() works when no FD is registered. +Make sure selectors.EpollSelector.select() works when no FD is registered. .. diff --git a/Misc/NEWS.d/3.5.2rc1.rst b/Misc/NEWS.d/3.5.2rc1.rst index 3036625d735821..d891fa0880dad1 100644 --- a/Misc/NEWS.d/3.5.2rc1.rst +++ b/Misc/NEWS.d/3.5.2rc1.rst @@ -2005,7 +2005,7 @@ Adds validation of ucrtbase[d].dll version with warning for old versions. .. nonce: 102DA- .. section: Build -Avoid error about nonexistant fileblocks.o file by using a lower-level check +Avoid error about nonexistent fileblocks.o file by using a lower-level check for st_blocks in struct stat. .. diff --git a/Misc/NEWS.d/3.5.4rc1.rst b/Misc/NEWS.d/3.5.4rc1.rst index f261ddb3a2d347..04a035a41e7461 100644 --- a/Misc/NEWS.d/3.5.4rc1.rst +++ b/Misc/NEWS.d/3.5.4rc1.rst @@ -913,7 +913,7 @@ Fixed infinite recursion in the repr of uninitialized ctypes.CDLL instances. Fixed race condition in C implementation of functools.lru_cache. KeyError could be raised when cached function with full cache was simultaneously -called from differen threads with the same uncached arguments. +called from different threads with the same uncached arguments. .. diff --git a/Misc/NEWS.d/3.6.0a1.rst b/Misc/NEWS.d/3.6.0a1.rst index dc08e42fb7e10b..3fa356c56d94a0 100644 --- a/Misc/NEWS.d/3.6.0a1.rst +++ b/Misc/NEWS.d/3.6.0a1.rst @@ -3694,7 +3694,7 @@ Adds validation of ucrtbase[d].dll version with warning for old versions. .. nonce: 102DA- .. section: Build -Avoid error about nonexistant fileblocks.o file by using a lower-level check +Avoid error about nonexistent fileblocks.o file by using a lower-level check for st_blocks in struct stat. .. diff --git a/Misc/NEWS.d/3.6.0b1.rst b/Misc/NEWS.d/3.6.0b1.rst index bd0e0a7c58d12e..3fbae5c6a4b3a8 100644 --- a/Misc/NEWS.d/3.6.0b1.rst +++ b/Misc/NEWS.d/3.6.0b1.rst @@ -1148,7 +1148,7 @@ dict constraint in ForwardRef._eval_type (upstream #252) .. nonce: hxh6_h .. section: Library -Make ``_normalize`` parameter to ``Fraction`` constuctor keyword-only, so +Make ``_normalize`` parameter to ``Fraction`` constructor keyword-only, so that ``Fraction(2, 3, 4)`` now raises ``TypeError``. .. diff --git a/Misc/NEWS.d/3.6.0rc1.rst b/Misc/NEWS.d/3.6.0rc1.rst index c44dec324d2fbf..15769f950db239 100644 --- a/Misc/NEWS.d/3.6.0rc1.rst +++ b/Misc/NEWS.d/3.6.0rc1.rst @@ -48,7 +48,7 @@ they still are deprecated and will be disabled in 3.7. .. section: Library Fix a regression introduced in warnings.catch_warnings(): call -warnings.showwarning() if it was overriden inside the context manager. +warnings.showwarning() if it was overridden inside the context manager. .. diff --git a/Misc/NEWS.d/3.6.1rc1.rst b/Misc/NEWS.d/3.6.1rc1.rst index 1f9fb13f69701b..58fd1b0624b2de 100644 --- a/Misc/NEWS.d/3.6.1rc1.rst +++ b/Misc/NEWS.d/3.6.1rc1.rst @@ -435,7 +435,7 @@ Fix an important omission by adding Deque to the typing module. Fixed race condition in C implementation of functools.lru_cache. KeyError could be raised when cached function with full cache was simultaneously -called from differen threads with the same uncached arguments. +called from different threads with the same uncached arguments. .. diff --git a/Misc/NEWS.d/3.6.3rc1.rst b/Misc/NEWS.d/3.6.3rc1.rst index 759436028b661c..4dc2eef5d3b61b 100644 --- a/Misc/NEWS.d/3.6.3rc1.rst +++ b/Misc/NEWS.d/3.6.3rc1.rst @@ -877,7 +877,7 @@ The affected events are '<>', '<>', '<>', '<>', and '<>'. Any (global) customizations made before 3.6.3 will not affect their keyset-specific customization after 3.6.3. and vice versa. -Inital patch by Charles Wohlganger. +Initial patch by Charles Wohlganger. .. diff --git a/Misc/NEWS.d/3.7.0a1.rst b/Misc/NEWS.d/3.7.0a1.rst index f9cd59c8d4bd79..8a304e8755e6b2 100644 --- a/Misc/NEWS.d/3.7.0a1.rst +++ b/Misc/NEWS.d/3.7.0a1.rst @@ -3651,7 +3651,7 @@ regular expression objects. Fixed race condition in C implementation of functools.lru_cache. KeyError could be raised when cached function with full cache was simultaneously -called from differen threads with the same uncached arguments. +called from different threads with the same uncached arguments. .. diff --git a/Misc/NEWS.d/3.8.0.rst b/Misc/NEWS.d/3.8.0.rst new file mode 100644 index 00000000000000..b7e681f8333bd5 --- /dev/null +++ b/Misc/NEWS.d/3.8.0.rst @@ -0,0 +1,186 @@ +.. bpo: 38469 +.. date: 2019-10-13-23-41-38 +.. nonce: 9kmuQj +.. release date: 2019-10-14 +.. section: Core and Builtins + +Fixed a bug where the scope of named expressions was not being resolved +correctly in the presence of the *global* keyword. Patch by Pablo Galindo. + +.. + +.. bpo: 38379 +.. date: 2019-10-09-16-50-52 +.. nonce: oz5qZx +.. section: Core and Builtins + +When cyclic garbage collection (gc) runs finalizers that resurrect +unreachable objects, the current gc run ends, without collecting any cyclic +trash. However, the statistics reported by ``collect()`` and +``get_stats()`` claimed that all cyclic trash found was collected, and that +the resurrected objects were collected. Changed the stats to report that +none were collected. + +.. + +.. bpo: 38449 +.. date: 2019-10-11-18-49-00 +.. nonce: 9TWMlz +.. section: Library + +Revert GH-15522, which introduces a regression in +:meth:`mimetypes.guess_type` due to improper handling of filenames as urls. + +.. + +.. bpo: 38431 +.. date: 2019-10-10-16-53-00 +.. nonce: d5wzNp +.. section: Library + +Fix ``__repr__`` method for :class:`dataclasses.InitVar` to support typing +objects, patch by Samuel Colvin. + +.. + +.. bpo: 38109 +.. date: 2019-10-10-00-25-28 +.. nonce: 9w-IGF +.. section: Library + +Add missing :data:`stat.S_IFDOOR`, :data:`stat.S_IFPORT`, +:data:`stat.S_IFWHT`, :func:`stat.S_ISDOOR`, :func:`stat.S_ISPORT`, and +:func:`stat.S_ISWHT` values to the Python implementation of :mod:`stat`. + +.. + +.. bpo: 38405 +.. date: 2019-10-08-11-18-40 +.. nonce: 0-7e7s +.. section: Library + +Nested subclasses of :class:`typing.NamedTuple` are now pickleable. + +.. + +.. bpo: 38332 +.. date: 2019-10-05-02-07-52 +.. nonce: hwrPN7 +.. section: Library + +Prevent :exc:`KeyError` thrown by :func:`_encoded_words.decode` when given +an encoded-word with invalid content-type encoding from propagating all the +way to :func:`email.message.get`. + +.. + +.. bpo: 38341 +.. date: 2019-10-01-21-06-18 +.. nonce: uqwgU_ +.. section: Library + +Add :exc:`smtplib.SMTPNotSupportedError` to the :mod:`smtplib` exported +names. + +.. + +.. bpo: 13153 +.. date: 2019-09-29-22-47-37 +.. nonce: 0mO9qR +.. section: Library + +OS native encoding is now used for converting between Python strings and Tcl +objects. This allows to display, copy and paste to clipboard emoji and +other non-BMP characters. Converting strings from Tcl to Python and back +now never fails (except MemoryError). + +.. + +.. bpo: 38294 +.. date: 2019-09-27-23-37-41 +.. nonce: go_jFf +.. section: Documentation + +Add list of no-longer-escaped chars to re.escape documentation + +.. + +.. bpo: 37531 +.. date: 2019-10-08-16-42-05 +.. nonce: 7v-_Ca +.. section: Tests + +On timeout, regrtest no longer attempts to call ``popen.communicate()`` +again: it can hang until all child processes using stdout and stderr pipes +completes. Kill the worker process and ignores its output. Change also the +faulthandler timeout of the main process from 1 minute to 5 minutes, for +Python slowest buildbots. + +.. + +.. bpo: 38344 +.. date: 2019-10-05-05-50-58 +.. nonce: scr2LO +.. section: Windows + +Fix error message in activate.bat + +.. + +.. bpo: 38359 +.. date: 2019-10-03-08-04-14 +.. nonce: wzwsl_ +.. section: Windows + +Ensures ``pyw.exe`` launcher reads correct registry key. + +.. + +.. bpo: 38355 +.. date: 2019-10-02-15-38-49 +.. nonce: n3AWX6 +.. section: Windows + +Fixes ``ntpath.realpath`` failing on ``sys.executable``. + +.. + +.. bpo: 36698 +.. date: 2019-10-04-18-03-09 +.. nonce: BKcmom +.. section: IDLE + +IDLE no longer fails when write non-encodable characters to stderr. It now +escapes them with a backslash, as the regular Python interpreter. Added the +``errors`` field to the standard streams. + +.. + +.. bpo: 38118 +.. date: 2019-10-08-15-07-52 +.. nonce: pIZD6H +.. section: Tools/Demos + +Update Valgrind suppression file to ignore a false alarm in +:c:func:`PyUnicode_Decode` when using GCC builtin strcmp(). + +.. + +.. bpo: 38347 +.. date: 2019-10-02-09-48-42 +.. nonce: 2Tq5D1 +.. section: Tools/Demos + +pathfix.py: Assume all files that end on '.py' are Python scripts when +working recursively. + +.. + +.. bpo: 38395 +.. date: 2019-10-08-01-23-24 +.. nonce: MJ6Ey9 +.. section: C API + +Fix a crash in :class:`weakref.proxy` objects due to incorrect lifetime +management when calling some associated methods that may delete the last +reference to object being referenced by the proxy. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/3.8.0a1.rst b/Misc/NEWS.d/3.8.0a1.rst index f4b0a048330004..96208c88d32b3c 100644 --- a/Misc/NEWS.d/3.8.0a1.rst +++ b/Misc/NEWS.d/3.8.0a1.rst @@ -550,7 +550,7 @@ The *lineno* and *col_offset* attributes of the AST for decorated function and class refer now to the position of the corresponding ``def``, ``async def`` and ``class`` instead of the position of the first decorator. This leads to more correct line reporting in tracing. This is the only case when -the position of child AST nodes can preceed the position of the parent AST +the position of child AST nodes can precede the position of the parent AST node. .. @@ -1358,7 +1358,7 @@ Improved syntax error messages for unbalanced parentheses. .. section: Core and Builtins The list constructor will pre-size and not over-allocate when the input -lenght is known. +length is known. .. @@ -2366,7 +2366,7 @@ running external programs like ``cmd /c ver``. Previously, calling the strftime() method on a datetime object with a trailing '%' in the format string would result in an exception. However, -this only occured when the datetime C module was being used; the python +this only occurred when the datetime C module was being used; the python implementation did not match this behavior. Datetime is now PEP-399 compliant, and will not throw an exception on a trailing '%'. @@ -2418,7 +2418,7 @@ over browsers in the ``BROWSER`` environment variable. .. nonce: eSLKBE .. section: Library -Avoid stripping trailing whitespace in doctest fancy diff. Orignial patch by +Avoid stripping trailing whitespace in doctest fancy diff. Original patch by R. David Murray & Jairo Trad. Enhanced by Sanyam Khurana. .. @@ -5278,7 +5278,7 @@ Improved error handling and fixed a reference leak in .. nonce: zncfvW .. section: Library -Deleting a key from a read-only dbm database raises module specfic error +Deleting a key from a read-only dbm database raises module specific error instead of KeyError. .. diff --git a/Misc/NEWS.d/3.8.0a3.rst b/Misc/NEWS.d/3.8.0a3.rst index a7397b520cb102..66308c6bca2e26 100644 --- a/Misc/NEWS.d/3.8.0a3.rst +++ b/Misc/NEWS.d/3.8.0a3.rst @@ -173,7 +173,7 @@ Update Unicode databases to version 12.0.0. .. nonce: dZemNt .. section: Core and Builtins -Fix a segfault occuring when sorting a list of heterogeneous values. Patch +Fix a segfault occurring when sorting a list of heterogeneous values. Patch contributed by Rémi Lapeyre and Elliot Gorokhovsky. .. @@ -830,7 +830,8 @@ Refactor class variables to instance variables in colorizer. .. nonce: WbaRJW .. section: IDLE -Increase test coverage of idlelib.autocomplete by 30%. +Increase test coverage of idlelib.autocomplete by 30%. Patch by Louie +Lu .. diff --git a/Misc/NEWS.d/3.8.0a4.rst b/Misc/NEWS.d/3.8.0a4.rst index 80e01d97a04337..995aa94a7405e4 100644 --- a/Misc/NEWS.d/3.8.0a4.rst +++ b/Misc/NEWS.d/3.8.0a4.rst @@ -1110,7 +1110,7 @@ Add ``-fmax-type-align=8`` to CFLAGS when clang compiler is detected. The pymalloc memory allocator aligns memory on 8 bytes. On x86-64, clang expects alignment on 16 bytes by default and so uses MOVAPS instruction which can lead to segmentation fault. Instruct clang that Python is limited to -alignemnt on 8 bytes to use MOVUPS instruction instead: slower but don't +alignment on 8 bytes to use MOVUPS instruction instead: slower but don't trigger a SIGSEGV if the memory is not aligned on 16 bytes. Sadly, the flag must be added to ``CFLAGS`` and not just ``CFLAGS_NODIST``, since third party C extensions can have the same issue. diff --git a/Misc/NEWS.d/3.8.0b1.rst b/Misc/NEWS.d/3.8.0b1.rst index d083983642e7a0..43a88a37c5cb08 100644 --- a/Misc/NEWS.d/3.8.0b1.rst +++ b/Misc/NEWS.d/3.8.0b1.rst @@ -355,7 +355,7 @@ standard library. They now inherit ``__str__()`` from :class:`object`. .. -.. bpo: 36774 +.. bpo: 36817 .. date: 2019-05-02-11-48-08 .. nonce: ZqbJ1J .. section: Core and Builtins @@ -808,7 +808,7 @@ detect classes that can be passed to `hex()`, `oct()` and `bin()`. .. nonce: LoeUNh .. section: Library -Implement ``unittest.AsyncTestCase`` to help testing asyncio-based code. +Implement ``unittest.IsolatedAsyncioTestCase`` to help testing asyncio-based code. .. @@ -1262,7 +1262,7 @@ Reinitialize logging.Handler locks in forked child processes instead of attempting to acquire them all in the parent before forking only to be released in the child process. The acquire/release pattern was leading to deadlocks in code that has implemented any form of chained logging handlers -that depend upon one another as the lock acquision order cannot be +that depend upon one another as the lock acquisition order cannot be guaranteed. .. @@ -1613,7 +1613,7 @@ versions. .. section: Documentation Improve documentation of the stdin, stdout, and stderr arguments of of the -``asyncio.subprocess_exec`` function to specficy which values are supported. +``asyncio.subprocess_exec`` function to specify which values are supported. Also mention that decoding as text is not supported. Add a few tests to verify that the various values passed to the std* @@ -1951,7 +1951,7 @@ sys.exit(). .. -.. bpo: 13102 +.. bpo: 36807 .. date: 2019-05-05-16-27-53 .. nonce: AGNWYJ .. section: IDLE diff --git a/Misc/NEWS.d/3.8.0b2.rst b/Misc/NEWS.d/3.8.0b2.rst new file mode 100644 index 00000000000000..f462e753956b48 --- /dev/null +++ b/Misc/NEWS.d/3.8.0b2.rst @@ -0,0 +1,933 @@ +.. bpo: 37363 +.. date: 2019-07-01-10-31-14 +.. nonce: fSjatj +.. release date: 2019-07-04 +.. section: Security + +Adds audit events for the range of supported run commands (see +:ref:`using-on-general`). + +.. + +.. bpo: 37463 +.. date: 2019-07-01-08-46-14 +.. nonce: 1CHwjE +.. section: Security + +ssl.match_hostname() no longer accepts IPv4 addresses with additional text +after the address and only quad-dotted notation without trailing +whitespaces. Some inet_aton() implementations ignore whitespace and all data +after whitespace, e.g. '127.0.0.1 whatever'. + +.. + +.. bpo: 37363 +.. date: 2019-06-21-15-58-59 +.. nonce: diouyl +.. section: Security + +Adds audit events for :mod:`ensurepip`, :mod:`ftplib`, :mod:`glob`, +:mod:`imaplib`, :mod:`nntplib`, :mod:`pdb`, :mod:`poplib`, :mod:`shutil`, +:mod:`smtplib`, :mod:`sqlite3`, :mod:`subprocess`, :mod:`telnetlib`, +:mod:`tempfile` and :mod:`webbrowser`, as well as :func:`os.listdir`, +:func:`os.scandir` and :func:`breakpoint`. + +.. + +.. bpo: 37364 +.. date: 2019-06-21-14-42-53 +.. nonce: IIRc2s +.. section: Security + +:func:`io.open_code` is now used when reading :file:`.pth` files. + +.. + +.. bpo: 34631 +.. date: 2019-06-17-09-34-25 +.. nonce: DBfM4j +.. section: Security + +Updated OpenSSL to 1.1.1c in Windows installer + +.. + +.. bpo: 37467 +.. date: 2019-07-01-12-22-44 +.. nonce: u-XyEu +.. section: Core and Builtins + +Fix :func:`sys.excepthook` and :c:func:`PyErr_Display` if a filename is a +bytes string. For example, for a SyntaxError exception where the filename +attribute is a bytes string. + +.. + +.. bpo: 37417 +.. date: 2019-06-26-18-41-00 +.. nonce: VsZeHL +.. section: Core and Builtins + +:meth:`bytearray.extend` now correctly handles errors that arise during +iteration. Patch by Brandt Bucher. + +.. + +.. bpo: 24214 +.. date: 2019-06-22-12-45-20 +.. nonce: hIiHeD +.. section: Core and Builtins + +Improved support of the surrogatepass error handler in the UTF-8 and UTF-16 +incremental decoders. + +.. + +.. bpo: 35224 +.. date: 2019-06-17-06-03-55 +.. nonce: FHWPGv +.. section: Core and Builtins + +Reverse evaluation order of key: value in dict comprehensions as proposed in +PEP 572. I.e. in ``{k: v for ...}``, ``k`` will be evaluated before ``v``. + +.. + +.. bpo: 37316 +.. date: 2019-06-17-03-53-16 +.. nonce: LytDX_ +.. section: Core and Builtins + +Fix the :c:func:`PySys_Audit` call in :class:`mmap.mmap`. + +.. + +.. bpo: 37269 +.. date: 2019-06-14-06-32-33 +.. nonce: SjVVAe +.. section: Core and Builtins + +Fix a bug in the peephole optimizer that was not treating correctly constant +conditions with binary operators. Patch by Pablo Galindo. + +.. + +.. bpo: 37213 +.. date: 2019-06-11-11-15-19 +.. nonce: UPii5K +.. section: Core and Builtins + +Handle correctly negative line offsets in the peephole optimizer. Patch by +Pablo Galindo. + +.. + +.. bpo: 37219 +.. date: 2019-06-10-23-18-31 +.. nonce: jPSufq +.. section: Core and Builtins + +Remove errorneous optimization for empty set differences. + +.. + +.. bpo: 36922 +.. date: 2019-06-06-13-59-52 +.. nonce: EMZ3TF +.. section: Core and Builtins + +Slot functions optimize any callable with ``Py_TPFLAGS_METHOD_DESCRIPTOR`` +instead of only instances of ``function``. + +.. + +.. bpo: 36974 +.. date: 2019-06-06-11-00-55 +.. nonce: wdzzym +.. section: Core and Builtins + +The slot ``tp_vectorcall_offset`` is inherited unconditionally to support +``super().__call__()`` when the base class uses vectorcall. + +.. + +.. bpo: 37160 +.. date: 2019-06-05-09-24-17 +.. nonce: O3IAY3 +.. section: Core and Builtins + +:func:`threading.get_native_id` now also supports NetBSD. + +.. + +.. bpo: 37077 +.. date: 2019-05-28-11-47-44 +.. nonce: S1h0Fc +.. section: Core and Builtins + +Add :func:`threading.get_native_id` support for AIX. Patch by M. Felt + +.. + +.. bpo: 37440 +.. date: 2019-06-28-16-40-17 +.. nonce: t3wX-N +.. section: Library + +http.client now enables TLS 1.3 post-handshake authentication for default +context or if a cert_file is passed to HTTPSConnection. + +.. + +.. bpo: 37437 +.. date: 2019-06-27-20-33-50 +.. nonce: du39_A +.. section: Library + +Update vendorized expat version to 2.2.7. + +.. + +.. bpo: 37428 +.. date: 2019-06-27-13-27-02 +.. nonce: _wcwUd +.. section: Library + +SSLContext.post_handshake_auth = True no longer sets +SSL_VERIFY_POST_HANDSHAKE verify flag for client connections. Although the +option is documented as ignored for clients, OpenSSL implicitly enables cert +chain validation when the flag is set. + +.. + +.. bpo: 37420 +.. date: 2019-06-26-22-25-05 +.. nonce: CxFJ09 +.. section: Library + +:func:`os.sched_setaffinity` now correctly handles errors that arise during +iteration over its ``mask`` argument. Patch by Brandt Bucher. + +.. + +.. bpo: 37412 +.. date: 2019-06-26-16-28-59 +.. nonce: lx0VjC +.. section: Library + +The :func:`os.getcwdb` function now uses the UTF-8 encoding on Windows, +rather than the ANSI code page: see :pep:`529` for the rationale. The +function is no longer deprecated on Windows. + +.. + +.. bpo: 29412 +.. date: 2019-06-25-19-27-25 +.. nonce: n4Zqdh +.. section: Library + +Fix IndexError in parsing a header value ending unexpectedly. Patch by +Abhilash Raj. + +.. + +.. bpo: 36546 +.. date: 2019-06-25-05-07-48 +.. nonce: RUcxaK +.. section: Library + +The *dist* argument for statistics.quantiles() is now positional only. The +current name doesn't reflect that the argument can be either a dataset or a +distribution. Marking the parameter as positional avoids confusion and +makes it possible to change the name later. + +.. + +.. bpo: 37394 +.. date: 2019-06-25-02-10-00 +.. nonce: srZ1zx +.. section: Library + +Fix a bug that was causing the :mod:`queue` module to fail if the +accelerator module was not available. Patch by Pablo Galindo. + +.. + +.. bpo: 33972 +.. date: 2019-06-15-14-39-50 +.. nonce: XxnNPw +.. section: Library + +Email with single part but content-type set to ``multipart/*`` doesn't raise +AttributeError anymore. + +.. + +.. bpo: 37280 +.. date: 2019-06-14-13-30-47 +.. nonce: Fxur0F +.. section: Library + +Use threadpool for reading from file for sendfile fallback mode. + +.. + +.. bpo: 37279 +.. date: 2019-06-14-13-25-56 +.. nonce: OHlW6l +.. section: Library + +Fix asyncio sendfile support when sendfile sends extra data in fallback +mode. + +.. + +.. bpo: 19865 +.. date: 2019-06-14-08-30-16 +.. nonce: FRGH4I +.. section: Library + +:func:`ctypes.create_unicode_buffer()` now also supports non-BMP characters +on platforms with 16-bit :c:type:`wchar_t` (for example, Windows and AIX). + +.. + +.. bpo: 37210 +.. date: 2019-06-12-16-10-50 +.. nonce: r4yMg6 +.. section: Library + +Allow pure Python implementation of :mod:`pickle` to work even when the C +:mod:`_pickle` module is unavailable. + +.. + +.. bpo: 35922 +.. date: 2019-06-11-19-34-29 +.. nonce: rxpzWr +.. section: Library + +Fix :meth:`RobotFileParser.crawl_delay` and +:meth:`RobotFileParser.request_rate` to return ``None`` rather than raise +:exc:`AttributeError` when no relevant rule is defined in the robots.txt +file. Patch by Rémi Lapeyre. + +.. + +.. bpo: 35766 +.. date: 2019-06-11-16-41-40 +.. nonce: v1Kj-T +.. section: Library + +Change the format of feature_version to be a (major, minor) tuple. + +.. + +.. bpo: 36607 +.. date: 2019-06-11-13-52-04 +.. nonce: 5_mJkQ +.. section: Library + +Eliminate :exc:`RuntimeError` raised by :func:`asyncio.all_tasks()` if +internal tasks weak set is changed by another thread during iteration. + +.. + +.. bpo: 18748 +.. date: 2019-06-11-01-54-19 +.. nonce: ADqCkq +.. section: Library + +:class:`_pyio.IOBase` destructor now does nothing if getting the ``closed`` +attribute fails to better mimick :class:`_io.IOBase` finalizer. + +.. + +.. bpo: 36402 +.. date: 2019-06-11-00-35-02 +.. nonce: b0IJVp +.. section: Library + +Fix a race condition at Python shutdown when waiting for threads. Wait until +the Python thread state of all non-daemon threads get deleted (join all +non-daemon threads), rather than just wait until non-daemon Python threads +complete. + +.. + +.. bpo: 34886 +.. date: 2019-06-08-16-03-19 +.. nonce: Ov-pc9 +.. section: Library + +Fix an unintended ValueError from :func:`subprocess.run` when checking for +conflicting `input` and `stdin` or `capture_output` and `stdout` or `stderr` +args when they were explicitly provided but with `None` values within a +passed in `**kwargs` dict rather than as passed directly by name. Patch +contributed by Rémi Lapeyre. + +.. + +.. bpo: 37173 +.. date: 2019-06-08-11-33-48 +.. nonce: 0e_8gS +.. section: Library + +The exception message for ``inspect.getfile()`` now correctly reports the +passed class rather than the builtins module. + +.. + +.. bpo: 37178 +.. date: 2019-06-07-17-16-09 +.. nonce: Day_oB +.. section: Library + +Give math.perm() a one argument form that means the same as +math.factorial(). + +.. + +.. bpo: 37178 +.. date: 2019-06-07-17-11-34 +.. nonce: b1StSv +.. section: Library + +For math.perm(n, k), let k default to n, giving the same result as +factorial. + +.. + +.. bpo: 37163 +.. date: 2019-06-07-08-18-05 +.. nonce: 36JkUh +.. section: Library + +Deprecated passing ``obj`` argument of :func:`dataclasses.replace` as +keyword argument. + +.. + +.. bpo: 37165 +.. date: 2019-06-05-11-48-19 +.. nonce: V_rwfE +.. section: Library + +Converted _collections._count_elements to use the Argument Clinic. + +.. + +.. bpo: 34767 +.. date: 2019-06-04-23-44-52 +.. nonce: BpDShN +.. section: Library + +Do not always create a :class:`collections.deque` in :class:`asyncio.Lock`. + +.. + +.. bpo: 37158 +.. date: 2019-06-04-22-25-38 +.. nonce: JKm15S +.. section: Library + +Speed-up statistics.fmean() by switching from a function to a generator. + +.. + +.. bpo: 37150 +.. date: 2019-06-04-14-44-41 +.. nonce: TTzHxj +.. section: Library + +`argparse._ActionsContainer.add_argument` now throws error, if someone +accidentally pass FileType class object instead of instance of FileType as +`type` argument + +.. + +.. bpo: 35621 +.. date: 2019-05-28-19-03-46 +.. nonce: Abc1lf +.. section: Library + +Support running asyncio subprocesses when execution event loop in a thread +on UNIX. + +.. + +.. bpo: 36520 +.. date: 2019-05-28-02-37-00 +.. nonce: W4tday +.. section: Library + +Lengthy email headers with UTF-8 characters are now properly encoded when +they are folded. Patch by Jeffrey Kintscher. + +.. + +.. bpo: 30835 +.. date: 2019-05-27-15-29-46 +.. nonce: 3FoaWH +.. section: Library + +Fixed a bug in email parsing where a message with invalid bytes in +content-transfer-encoding of a multipart message can cause an +AttributeError. Patch by Andrew Donnellan. + +.. + +.. bpo: 35805 +.. date: 2019-05-17-15-11-08 +.. nonce: E4YwYz +.. section: Library + +Add parser for Message-ID header and add it to default HeaderRegistry. This +should prevent folding of Message-ID using RFC 2048 encoded words. + +.. + +.. bpo: 35070 +.. date: 2019-05-09-18-50-55 +.. nonce: 4vaqNL +.. section: Library + +posix.getgrouplist() now works correctly when the user belongs to +NGROUPS_MAX supplemental groups. Patch by Jeffrey Kintscher. + +.. + +.. bpo: 32627 +.. date: 2019-02-03-19-13-08 +.. nonce: b68f64 +.. section: Library + +Fix compile error when ``_uuid`` headers conflicting included. + +.. + +.. bpo: 11122 +.. date: 2018-11-12-19-08-50 +.. nonce: Gj7BQn +.. section: Library + +Distutils won't check for rpmbuild in specified paths only. + +.. + +.. bpo: 4963 +.. date: 2017-08-15-11-24-41 +.. nonce: LRYres +.. section: Library + +Fixed non-deterministic behavior related to mimetypes extension mapping and +module reinitialization. + +.. + +.. bpo: 34903 +.. date: 2019-06-17-09-36-46 +.. nonce: r_wGRc +.. section: Documentation + +Documented that in :meth:`datetime.datetime.strptime()`, the leading zero in +some two-digit formats is optional. Patch by Mike Gleen. + +.. + +.. bpo: 37421 +.. date: 2019-07-03-00-05-28 +.. nonce: ORGRSG +.. section: Tests + +test_distutils.test_build_ext() is now able to remove the temporary +directory on Windows: don't import the newly built C extension ("xx") in the +current process, but test it in a separated process. + +.. + +.. bpo: 37421 +.. date: 2019-07-02-23-29-06 +.. nonce: WEfc5A +.. section: Tests + +test_concurrent_futures now cleans up multiprocessing to remove immediately +temporary directories created by multiprocessing.util.get_temp_dir(). + +.. + +.. bpo: 37421 +.. date: 2019-07-02-23-20-35 +.. nonce: HCkKWz +.. section: Tests + +test_winconsoleio doesn't leak a temporary file anymore: use +tempfile.TemporaryFile() to remove it when the test completes. + +.. + +.. bpo: 37421 +.. date: 2019-07-01-19-57-26 +.. nonce: NFH1f0 +.. section: Tests + +multiprocessing tests now explicitly call ``_run_finalizers()`` to +immediately remove temporary directories created by tests. + +.. + +.. bpo: 37199 +.. date: 2019-06-29-23-56-28 +.. nonce: FHDsLf +.. section: Tests + +Fix test failures when IPv6 is unavailable or disabled. + +.. + +.. bpo: 37335 +.. date: 2019-06-28-16-37-52 +.. nonce: o5S2hY +.. section: Tests + +Remove no longer necessary code from c locale coercion tests + +.. + +.. bpo: 37421 +.. date: 2019-06-27-00-37-59 +.. nonce: rVJb3x +.. section: Tests + +Fix test_shutil to no longer leak temporary files. + +.. + +.. bpo: 37411 +.. date: 2019-06-26-15-28-45 +.. nonce: 5lGNhM +.. section: Tests + +Fix test_wsgiref.testEnviron() to no longer depend on the environment +variables (don't fail if "X" variable is set). + +.. + +.. bpo: 37400 +.. date: 2019-06-25-16-02-43 +.. nonce: cx_EWv +.. section: Tests + +Fix test_os.test_chown(): use os.getgroups() rather than grp.getgrall() to +get groups. Rename also the test to test_chown_gid(). + +.. + +.. bpo: 37359 +.. date: 2019-06-24-10-47-07 +.. nonce: CkdtyO +.. section: Tests + +Add --cleanup option to python3 -m test to remove ``test_python_*`` +directories of previous failed jobs. Add "make cleantest" to run ``python3 +-m test --cleanup``. + +.. + +.. bpo: 37362 +.. date: 2019-06-21-15-47-33 +.. nonce: D3xppx +.. section: Tests + +test_gdb no longer fails if it gets an "unexpected" message on stderr: it +now ignores stderr. The purpose of test_gdb is to test that python-gdb.py +commands work as expected, not to test gdb. + +.. + +.. bpo: 35998 +.. date: 2019-06-14-17-05-49 +.. nonce: yX82oD +.. section: Tests + +Avoid TimeoutError in test_asyncio: test_start_tls_server_1() + +.. + +.. bpo: 37278 +.. date: 2019-06-14-12-21-47 +.. nonce: z0HUOr +.. section: Tests + +Fix test_asyncio ProactorLoopCtrlC: join the thread to prevent leaking a +running thread and leaking a reference. + +.. + +.. bpo: 37261 +.. date: 2019-06-13-12-19-56 +.. nonce: NuKFVo +.. section: Tests + +Fix :func:`test.support.catch_unraisable_exception`: its __exit__() method +now ignores unraisable exception raised when clearing its ``unraisable`` +attribute. + +.. + +.. bpo: 37169 +.. date: 2019-06-07-12-23-15 +.. nonce: yfXTFg +.. section: Tests + +Rewrite ``_PyObject_IsFreed()`` unit tests. + +.. + +.. bpo: 37153 +.. date: 2019-06-04-18-30-39 +.. nonce: 711INB +.. section: Tests + +``test_venv.test_mutiprocessing()`` now explicitly calls +``pool.terminate()`` to wait until the pool completes. + +.. + +.. bpo: 28009 +.. date: 2019-04-11-07-59-43 +.. nonce: s85urF +.. section: Tests + +Modify the test_uuid logic to test when a program is available AND can be +used to obtain a MACADDR as basis for an UUID. Patch by M. Felt + +.. + +.. bpo: 37189 +.. date: 2019-06-17-09-40-59 +.. nonce: j5ebdT +.. section: Build + +Many ``PyRun_XXX()`` functions like :c:func:`PyRun_String` were no longer +exported in ``libpython38.dll`` by mistake. Export them again to fix the ABI +compatibiliy. + +.. + +.. bpo: 10945 +.. date: 2019-07-01-12-38-48 +.. nonce: s0YBHG +.. section: Windows + +Officially drop support for creating bdist_wininst installers on non-Windows +systems. + +.. + +.. bpo: 37369 +.. date: 2019-06-28-09-44-08 +.. nonce: 1iVpxq +.. section: Windows + +Fixes path for :data:`sys.executable` when running from the Microsoft Store. + +.. + +.. bpo: 37351 +.. date: 2019-06-20-12-50-32 +.. nonce: asTnVW +.. section: Windows + +Removes libpython38.a from standard Windows distribution. + +.. + +.. bpo: 35360 +.. date: 2019-06-18-09-05-08 +.. nonce: tdqSmo +.. section: Windows + +Update Windows builds to use SQLite 3.28.0. + +.. + +.. bpo: 37267 +.. date: 2019-06-13-04-15-51 +.. nonce: Ygo5ef +.. section: Windows + +On Windows, :func:`os.dup` no longer creates an inheritable fd when handling +a character file. + +.. + +.. bpo: 36779 +.. date: 2019-06-11-15-41-34 +.. nonce: 0TMw6f +.. section: Windows + +Ensure ``time.tzname`` is correct on Windows when the active code page is +set to CP_UTF7 or CP_UTF8. + +.. + +.. bpo: 34602 +.. date: 2019-07-02-01-06-47 +.. nonce: 10d4wl +.. section: macOS + +Avoid test suite failures on macOS by no longer calling resource.setrlimit +to increase the process stack size limit at runtime. The runtime change is +no longer needed since the interpreter is being built with a larger default +stack size. + +.. + +.. bpo: 35360 +.. date: 2019-06-18-08-58-30 +.. nonce: -CWbfy +.. section: macOS + +Update macOS installer to use SQLite 3.28.0. + +.. + +.. bpo: 34631 +.. date: 2019-06-18-00-30-40 +.. nonce: vSifcv +.. section: macOS + +Updated OpenSSL to 1.1.1c in macOS installer. + +.. + +.. bpo: 37325 +.. date: 2019-06-18-16-40-05 +.. nonce: GssOf1 +.. section: IDLE + +Fix tab focus traversal order for help source and custom run dialogs. + +.. + +.. bpo: 37321 +.. date: 2019-06-17-16-35-30 +.. nonce: zVTTGS +.. section: IDLE + +Both subprocess connection error messages now refer to the 'Startup failure' +section of the IDLE doc. + +.. + +.. bpo: 37177 +.. date: 2019-06-07-00-17-41 +.. nonce: voU6pQ +.. section: IDLE + +Properly 'attach' search dialogs to their main window so that they behave +like other dialogs and do not get hidden behind their main window. + +.. + +.. bpo: 37039 +.. date: 2019-06-04-23-27-33 +.. nonce: FN_fBf +.. section: IDLE + +Adjust "Zoom Height" to individual screens by momemtarily maximizing the +window on first use with a particular screen. Changing screen settings may +invalidate the saved height. While a window is maximized, "Zoom Height" has +no effect. + +.. + +.. bpo: 35763 +.. date: 2019-06-04-20-36-24 +.. nonce: 7XdoWz +.. section: IDLE + +Make calltip reminder about '/' meaning positional-only less obtrusive by +only adding it when there is room on the first line. + +.. + +.. bpo: 5680 +.. date: 2019-06-03-00-39-29 +.. nonce: VCQfOO +.. section: IDLE + +Add 'Run... Customized' to the Run menu to run a module with customized +settings. Any 'command line arguments' entered are added to sys.argv. One +can suppress the normal Shell main module restart. + +.. + +.. bpo: 36763 +.. date: 2019-06-28-15-49-16 +.. nonce: zrmgki +.. section: C API + +Add :func:`PyConfig_SetWideStringList` function. + +.. + +.. bpo: 28805 +.. date: 2019-06-14-14-03-51 +.. nonce: qZC0N_ +.. section: C API + +The :const:`METH_FASTCALL` calling convention has been documented. + +.. + +.. bpo: 37221 +.. date: 2019-06-12-11-45-36 +.. nonce: RhP1E7 +.. section: C API + +``tp_print`` is put back at the end of the ``PyTypeObject`` structure to +restore support for old code (in particular generated by Cython) setting +``tp_print = 0``. Note that ``tp_print`` will be removed entirely in Python +3.9. + +.. + +.. bpo: 37221 +.. date: 2019-06-11-02-50-38 +.. nonce: 4tClQT +.. section: C API + +The new function :c:func:`PyCode_NewWithPosOnlyArgs` allows to create code +objects like :c:func:`PyCode_New`, but with an extra *posonlyargcount* +parameter for indicating the number of positonal-only arguments. + +.. + +.. bpo: 37215 +.. date: 2019-06-10-15-32-34 +.. nonce: yzoNyU +.. section: C API + +Fix dtrace issue introduce by bpo-36842 + +.. + +.. bpo: 37191 +.. date: 2019-06-07-10-47-37 +.. nonce: iGL1_K +.. section: C API + +Python.h does not need compiler support for intermingled declarations (GCC's +``-Wdeclaration-after-statement``), which were added in 3.8.0 Beta 1. Note +that in Python 3.9, intermingled declarations will be needed again. + +.. + +.. bpo: 37170 +.. date: 2019-06-06-08-47-04 +.. nonce: hO_fpM +.. section: C API + +Fix the cast on error in :c:func:`PyLong_AsUnsignedLongLongMask()`. diff --git a/Misc/NEWS.d/3.8.0b3.rst b/Misc/NEWS.d/3.8.0b3.rst new file mode 100644 index 00000000000000..5e5225294ad8ce --- /dev/null +++ b/Misc/NEWS.d/3.8.0b3.rst @@ -0,0 +1,437 @@ +.. bpo: 37461 +.. date: 2019-07-16-08-11-00 +.. nonce: 1Ahz7O +.. release date: 2019-07-29 +.. section: Security + +Fix an infinite loop when parsing specially crafted email headers. Patch by +Abhilash Raj. + +.. + +.. bpo: 37593 +.. date: 2019-07-14-23-57-27 +.. nonce: yHSTwH +.. section: Core and Builtins + +Swap the positions of the *posonlyargs* and *args* parameters in the +constructor of :class:`ast.parameters` nodes. + +.. + +.. bpo: 36974 +.. date: 2019-06-11-12-59-38 +.. nonce: bVYmSA +.. section: Core and Builtins + +Implemented separate vectorcall functions for every calling convention of +builtin functions and methods. This improves performance for calls. + +.. + +.. bpo: 37697 +.. date: 2019-07-28-17-44-21 +.. nonce: 7UV5d0 +.. section: Library + +Syncronize ``importlib.metadata`` with `importlib_metadata 0.19 +`_, +improving handling of EGG-INFO files and fixing a crash when entry point +names contained colons. + +.. + +.. bpo: 37691 +.. date: 2019-07-26-22-30-01 +.. nonce: 1Li3rx +.. section: Library + +Let math.dist() accept coordinates as sequences (or iterables) rather than +just tuples. + +.. + +.. bpo: 37664 +.. date: 2019-07-24-18-27-44 +.. nonce: o-GYZC +.. section: Library + +Update wheels bundled with ensurepip (pip 19.2.1 and setuptools 41.0.1) + +.. + +.. bpo: 36324 +.. date: 2019-07-19-22-44-41 +.. nonce: 1VjywS +.. section: Library + +Make internal attributes for statistics.NormalDist() private. + +.. + +.. bpo: 37491 +.. date: 2019-07-17-06-54-43 +.. nonce: op0aMs +.. section: Library + +Fix ``IndexError`` when parsing email headers with unexpectedly ending +bare-quoted string value. Patch by Abhilash Raj. + +.. + +.. bpo: 37579 +.. date: 2019-07-13-10-59-43 +.. nonce: B1Tq9i +.. section: Library + +Return :exc:`NotImplemented` in Python implementation of ``__eq__`` for +:class:`~datetime.timedelta` and :class:`~datetime.time` when the other +object being compared is not of the same type to match C implementation. +Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 21478 +.. date: 2019-07-10-23-07-11 +.. nonce: cCw9rF +.. section: Library + +Record calls to parent when autospecced object is attached to a mock using +:func:`unittest.mock.attach_mock`. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 37502 +.. date: 2019-07-08-03-15-04 +.. nonce: qZGC4g +.. section: Library + +pickle.loads() no longer raises TypeError when the buffers argument is set +to None + +.. + +.. bpo: 37520 +.. date: 2019-07-07-21-09-08 +.. nonce: Gg0KD6 +.. section: Library + +Correct behavior for zipfile.Path.parent when the path object identifies a +subdirectory. + +.. + +.. bpo: 18374 +.. date: 2019-07-05-21-46-45 +.. nonce: qgE0H3 +.. section: Library + +Fix the ``.col_offset`` attribute of nested :class:`ast.BinOp` instances +which had a too large value in some situations. + +.. + +.. bpo: 37421 +.. date: 2019-07-03-12-47-52 +.. nonce: gR5hC8 +.. section: Library + +Fix :func:`multiprocessing.util.get_temp_dir` finalizer: clear also the +'tempdir' configuration of the current process, so next call to +``get_temp_dir()`` will create a new temporary directory, rather than +reusing the removed temporary directory. + +.. + +.. bpo: 37481 +.. date: 2019-07-02-13-08-30 +.. nonce: hd5k09 +.. section: Library + +The distutils ``bdist_wininst`` command is deprecated in Python 3.8, use +``bdist_wheel`` (wheel packages) instead. + +.. + +.. bpo: 26967 +.. date: 2019-06-23-12-46-10 +.. nonce: xEuem1 +.. section: Library + +An :class:`~argparse.ArgumentParser` with ``allow_abbrev=False`` no longer +disables grouping of short flags, such as ``-vv``, but only disables +abbreviation of long flags as documented. Patch by Zac Hatfield-Dodds. + +.. + +.. bpo: 37347 +.. date: 2019-06-20-14-23-48 +.. nonce: Gf9yYI +.. section: Library + +:meth:`sqlite3.Connection.create_aggregate`, +:meth:`sqlite3.Connection.create_function`, +:meth:`sqlite3.Connection.set_authorizer`, +:meth:`sqlite3.Connection.set_progress_handler` +:meth:`sqlite3.Connection.set_trace_callback` methods lead to segfaults if +some of these methods are called twice with an equal object but not the +same. Now callbacks are stored more carefully. Patch by Aleksandr Balezin. + +.. + +.. bpo: 36564 +.. date: 2019-04-08-13-00-13 +.. nonce: _n67m_ +.. section: Library + +Fix infinite loop in email header folding logic that would be triggered when +an email policy's max_line_length is not long enough to include the required +markup and any values in the message. Patch by Paul Ganssle + +.. + +.. bpo: 32910 +.. date: 2019-07-25-10-30-32 +.. nonce: caLLAe +.. section: Documentation + +Remove implementation-specific behaviour of how venv's Deactivate works. + +.. + +.. bpo: 37284 +.. date: 2019-07-13-12-58-20 +.. nonce: rP8WpB +.. section: Documentation + +Add a brief note to indicate that any new ``sys.implementation`` required +attributes must go through the PEP process. + +.. + +.. bpo: 30088 +.. date: 2019-07-13-12-43-01 +.. nonce: CIcBjy +.. section: Documentation + +Documented that :class:`mailbox.Maildir` constructor doesn't attempt to +verify the maildir folder layout correctness. Patch by Sviatoslav Sydorenko. + +.. + +.. bpo: 37521 +.. date: 2019-07-12-15-09-56 +.. nonce: 7tiFR- +.. section: Documentation + +Fix `importlib` examples to insert any newly created modules via +importlib.util.module_from_spec() immediately into sys.modules instead of +after calling loader.exec_module(). + +Thanks to Benjamin Mintz for finding the bug. + +.. + +.. bpo: 37456 +.. date: 2019-07-06-17-51-36 +.. nonce: lgAQHn +.. section: Documentation + +Slash ('/') is now part of syntax. + +.. + +.. bpo: 37487 +.. date: 2019-07-06-17-19-26 +.. nonce: QagfZ5 +.. section: Documentation + +Fix PyList_GetItem index description to include 0. + +.. + +.. bpo: 37149 +.. date: 2019-07-06-02-19-02 +.. nonce: NumHn3 +.. section: Documentation + +Replace the dead link to the Tkinter 8.5 reference by John Shipman, New +Mexico Tech, with a link to the archive.org copy. + +.. + +.. bpo: 37478 +.. date: 2019-07-06-00-57-27 +.. nonce: B0ioLw +.. section: Documentation + +Added possible exceptions to the description of os.chdir(). + +.. + +.. bpo: 37558 +.. date: 2019-07-11-10-33-56 +.. nonce: SKHRsL +.. section: Tests + +Fix test_shared_memory_cleaned_after_process_termination name handling + +.. + +.. bpo: 37526 +.. date: 2019-07-09-12-33-18 +.. nonce: vmm5y7 +.. section: Tests + +Add :func:`test.support.catch_threading_exception`: context manager catching +:class:`threading.Thread` exception using :func:`threading.excepthook`. + +.. + +.. bpo: 37421 +.. date: 2019-07-08-10-11-36 +.. nonce: OY77go +.. section: Tests + +test_concurrent_futures now explicitly stops the ForkServer instance if it's +running. + +.. + +.. bpo: 37421 +.. date: 2019-07-05-14-47-55 +.. nonce: n8o2to +.. section: Tests + +multiprocessing tests now stop the ForkServer instance if it's running: +close the "alive" file descriptor to ask the server to stop and then remove +its UNIX address. + +.. + +.. bpo: 36044 +.. date: 2019-07-11-01-28-24 +.. nonce: gIgfiJ +.. section: Build + +Reduce the number of unit tests run for the PGO generation task. This +speeds up the task by a factor of about 15x. Running the full unit test +suite is slow. This change may result in a slightly less optimized build +since not as many code branches will be executed. If you are willing to +wait for the much slower build, the old behavior can be restored using +'./configure [..] PROFILE_TASK="-m test --pgo-extended"'. We make no +guarantees as to which PGO task set produces a faster build. Users who care +should run their own relevant benchmarks as results can depend on the +environment, workload, and compiler tool chain. + +.. + +.. bpo: 37672 +.. date: 2019-07-24-14-36-28 +.. nonce: uKEVHN +.. section: Windows + +Switch Windows Store package's pip to use bundled :file:`pip.ini` instead of +:envvar:`PIP_USER` variable. + +.. + +.. bpo: 37692 +.. date: 2019-07-27-15-14-20 +.. nonce: TRHGjD +.. section: IDLE + +Improve highlight config sample with example shell interaction and better +labels for shell elements. + +.. + +.. bpo: 37628 +.. date: 2019-07-26-17-51-13 +.. nonce: kX4AUF +.. section: IDLE + +Settings dialog no longer expands with font size. + +.. + +.. bpo: 37627 +.. date: 2019-07-20-23-33-53 +.. nonce: dQhUNB +.. section: IDLE + +Initialize the Customize Run dialog with the command line arguments most +recently entered before. The user can optionally edit before submitting +them. + +.. + +.. bpo: 33610 +.. date: 2019-07-18-10-11-36 +.. nonce: xYqMLg +.. section: IDLE + +Fix code context not showing the correct context when first toggled on. + +.. + +.. bpo: 37530 +.. date: 2019-07-11-00-05-31 +.. nonce: AuyCyD +.. section: IDLE + +Optimize code context to reduce unneeded background activity. Font and +highlight changes now occur along with text changes instead of after a +random delay. + +.. + +.. bpo: 27452 +.. date: 2019-07-03-22-47-44 +.. nonce: nePPLi +.. section: IDLE + +Cleanup ``config.py`` by inlining ``RemoveFile`` and simplifying the +handling of ``file`` in ``CreateConfigHandlers``. + +.. + +.. bpo: 17535 +.. date: 2019-06-13-01-07-20 +.. nonce: K8i2St +.. section: IDLE + +Add optional line numbers for IDLE editor windows. Windows open without +line numbers unless set otherwise in the General tab of the configuration +dialog. + +.. + +.. bpo: 26806 +.. date: 2019-06-10-22-48-50 +.. nonce: Zltkum +.. section: IDLE + +To compensate for stack frames added by IDLE and avoid possible problems +with low recursion limits, add 30 to limits in the user code execution +process. Subtract 30 when reporting recursion limits to make this addition +mostly transparent. + +.. + +.. bpo: 36390 +.. date: 2019-03-21-08-35-00 +.. nonce: OdDCGk +.. section: IDLE + +Gather Format menu functions into format.py. Combine paragraph.py, +rstrip.py, and format methods from editor.py. + +.. + +.. bpo: 37675 +.. date: 2019-07-24-16-20-54 +.. nonce: 951Cvf +.. section: Tools/Demos + +2to3 now works when run from a zipped standard library. diff --git a/Misc/NEWS.d/3.8.0b4.rst b/Misc/NEWS.d/3.8.0b4.rst new file mode 100644 index 00000000000000..99c914815e52da --- /dev/null +++ b/Misc/NEWS.d/3.8.0b4.rst @@ -0,0 +1,733 @@ +.. bpo: 34155 +.. date: 2019-05-04-13-33-37 +.. nonce: MJll68 +.. release date: 2019-08-29 +.. section: Security + +Fix parsing of invalid email addresses with more than one ``@`` (e.g. +a@b@c.com.) to not return the part before 2nd ``@`` as valid email address. +Patch by maxking & jpic. + +.. + +.. bpo: 37947 +.. date: 2019-08-26-04-09-57 +.. nonce: mzAQtB +.. section: Core and Builtins + +Adjust correctly the recursion level in the symtable generation for named +expressions. Patch by Pablo Galindo. + +.. + +.. bpo: 37830 +.. date: 2019-08-17-18-41-59 +.. nonce: fNfMbz +.. section: Core and Builtins + +Fixed compilation of :keyword:`break` and :keyword:`continue` in the +:keyword:`finally` block when the corresponding :keyword:`try` block +contains :keyword:`return` with a non-constant value. + +.. + +.. bpo: 32912 +.. date: 2019-08-06-14-03-59 +.. nonce: UDwSMJ +.. section: Core and Builtins + +Reverted :issue:`32912`: emitting :exc:`SyntaxWarning` instead of +:exc:`DeprecationWarning` for invalid escape sequences in string and bytes +literals. + +.. + +.. bpo: 37757 +.. date: 2019-08-05-14-22-59 +.. nonce: lRv5HX +.. section: Core and Builtins + +:pep:`572`: As described in the PEP, assignment expressions now raise +:exc:`SyntaxError` when their interaction with comprehension scoping results +in an ambiguous target scope. + +The ``TargetScopeError`` subclass originally proposed by the PEP has been +removed in favour of just raising regular syntax errors for the disallowed +cases. + +.. + +.. bpo: 36311 +.. date: 2019-08-02-15-01-33 +.. nonce: uY5vt- +.. section: Core and Builtins + +Decoding bytes objects larger than 2GiB is faster and no longer fails when a +multibyte characters spans a chunk boundary. + +.. + +.. bpo: 37433 +.. date: 2019-06-27-15-01-14 +.. nonce: amNGqr +.. section: Core and Builtins + +Fix ``SyntaxError`` indicator printing too many spaces for multi-line +strings - by Anthony Sottile. + +.. + +.. bpo: 20523 +.. date: 2019-02-15-20-42-36 +.. nonce: rRLrvr +.. section: Core and Builtins + +``pdb.Pdb`` supports ~/.pdbrc in Windows 7. Patch by Tim Hopper and Dan +Lidral-Porter. + +.. + +.. bpo: 37834 +.. date: 2019-08-29-16-41-36 +.. nonce: FThnsh +.. section: Library + +Prevent shutil.rmtree exception when built on non-Windows system without fd +system call support, like older versions of macOS. + +.. + +.. bpo: 37965 +.. date: 2019-08-28-14-04-18 +.. nonce: 7xGE-C +.. section: Library + +Fix C compiler warning caused by distutils.ccompiler.CCompiler.has_function. + +.. + +.. bpo: 37960 +.. date: 2019-08-27-10-52-13 +.. nonce: CTY7Lw +.. section: Library + +``repr()`` of buffered and text streams now silences only expected +exceptions when get the value of "name" and "mode" attributes. + +.. + +.. bpo: 37951 +.. date: 2019-08-27-10-03-48 +.. nonce: MfRQgL +.. section: Library + +Most features of the subprocess module now work again in subinterpreters. +Only *preexec_fn* is restricted in subinterpreters. + +.. + +.. bpo: 36205 +.. date: 2019-08-27-03-53-26 +.. nonce: AfkGRl +.. section: Library + +Fix the rusage implementation of time.process_time() to correctly report the +sum of the system and user CPU time. + +.. + +.. bpo: 37950 +.. date: 2019-08-26-10-45-51 +.. nonce: -K1IKT +.. section: Library + +Fix :func:`ast.dump` when call with incompletely initialized node. + +.. + +.. bpo: 34679 +.. date: 2019-08-25-18-07-48 +.. nonce: HECzL7 +.. section: Library + +Restores instantiation of Windows IOCP event loops from the non-main thread. + +.. + +.. bpo: 36917 +.. date: 2019-08-25-14-56-42 +.. nonce: GBxdw2 +.. section: Library + +Add default implementation of the :meth:`ast.NodeVisitor.visit_Constant` +method which emits a deprecation warning and calls corresponding methody +``visit_Num()``, ``visit_Str()``, etc. + +.. + +.. bpo: 37798 +.. date: 2019-08-24-16-54-49 +.. nonce: 7mRQCk +.. section: Library + +Update test_statistics.py to verify that the statistics module works well +for both C and Python implementations. Patch by Dong-hee Na + +.. + +.. bpo: 26589 +.. date: 2019-08-23-00-55-19 +.. nonce: M1xyxG +.. section: Library + +Added a new status code to the http module: 451 +UNAVAILABLE_FOR_LEGAL_REASONS + +.. + +.. bpo: 37915 +.. date: 2019-08-22-16-13-27 +.. nonce: xyoZI5 +.. section: Library + +Fix a segmentation fault that appeared when comparing instances of +``datetime.timezone`` and ``datetime.tzinfo`` objects. Patch by Pablo +Galindo. + +.. + +.. bpo: 37868 +.. date: 2019-08-17-22-33-54 +.. nonce: hp64fi +.. section: Library + +Fix dataclasses.is_dataclass when given an instance that never raises +AttributeError in __getattr__. That is, an object that returns something +for __dataclass_fields__ even if it's not a dataclass. + +.. + +.. bpo: 37811 +.. date: 2019-08-14-21-41-07 +.. nonce: d1xYj7 +.. section: Library + +Fix ``socket`` module's ``socket.connect(address)`` function being unable to +establish connection in case of interrupted system call. The problem was +observed on all OSes which ``poll(2)`` system call can take only +non-negative integers and -1 as a timeout value. + +.. + +.. bpo: 21131 +.. date: 2019-08-14-15-34-23 +.. nonce: 0MMQRi +.. section: Library + +Fix ``faulthandler.register(chain=True)`` stack. faulthandler now allocates +a dedicated stack of ``SIGSTKSZ*2`` bytes, instead of just ``SIGSTKSZ`` +bytes. Calling the previous signal handler in faulthandler signal handler +uses more than ``SIGSTKSZ`` bytes of stack memory on some platforms. + +.. + +.. bpo: 37798 +.. date: 2019-08-14-13-51-24 +.. nonce: AmXrik +.. section: Library + +Add C fastpath for statistics.NormalDist.inv_cdf() Patch by Dong-hee Na + +.. + +.. bpo: 37819 +.. date: 2019-08-11-10-34-19 +.. nonce: LVJls- +.. section: Library + +Add Fraction.as_integer_ratio() to match the corresponding methods in bool, +int, float, and decimal. + +.. + +.. bpo: 37810 +.. date: 2019-08-10-12-33-27 +.. nonce: d4zbvB +.. section: Library + +Fix :mod:`difflib` ``?`` hint in diff output when dealing with tabs. Patch +by Anthony Sottile. + +.. + +.. bpo: 37772 +.. date: 2019-08-07-23-48-09 +.. nonce: hLCvdn +.. section: Library + +In ``zipfile.Path``, when adding implicit dirs, ensure that ancestral +directories are added and that duplicates are excluded. + +.. + +.. bpo: 28292 +.. date: 2019-08-04-11-47-58 +.. nonce: vkihH5 +.. section: Library + +Mark calendar.py helper functions as being private. The follows PEP 8 +guidance to maintain the style conventions in the module and it addresses a +known case of user confusion. + +.. + +.. bpo: 18049 +.. date: 2019-08-02-16-44-42 +.. nonce: OA4qBL +.. section: Library + +Add definition of THREAD_STACK_SIZE for AIX in Python/thread_pthread.h The +default thread stacksize caused crashes with the default recursion limit +Patch by M Felt + +.. + +.. bpo: 37738 +.. date: 2019-08-01-17-11-16 +.. nonce: A3WWcT +.. section: Library + +Fix the implementation of curses ``addch(str, color_pair)``: pass the color +pair to ``setcchar()``, instead of always passing 0 as the color pair. + +.. + +.. bpo: 37723 +.. date: 2019-07-31-16-49-01 +.. nonce: zq6tw8 +.. section: Library + +Fix performance regression on regular expression parsing with huge character +sets. Patch by Yann Vaginay. + +.. + +.. bpo: 32178 +.. date: 2019-07-30-22-41-05 +.. nonce: X-IFLe +.. section: Library + +Fix IndexError in :mod:`email` package when trying to parse invalid address +fields starting with ``:``. + +.. + +.. bpo: 37685 +.. date: 2019-07-28-22-25-25 +.. nonce: _3bN9f +.. section: Library + +Fixed comparisons of :class:`datetime.timedelta` and +:class:`datetime.timezone`. + +.. + +.. bpo: 37695 +.. date: 2019-07-27-20-21-03 +.. nonce: QANdvg +.. section: Library + +Correct :func:`curses.unget_wch` error message. Patch by Anthony Sottile. + +.. + +.. bpo: 37354 +.. date: 2019-07-25-10-28-40 +.. nonce: RT3_3H +.. section: Library + +Make Activate.ps1 Powershell script static to allow for signing it. + +.. + +.. bpo: 37664 +.. date: 2019-07-24-18-27-44 +.. nonce: o-GYZC +.. section: Library + +Update wheels bundled with ensurepip (pip 19.2.3 and setuptools 41.2.0) + +.. + +.. bpo: 37642 +.. date: 2019-07-21-20-59-31 +.. nonce: L61Bvy +.. section: Library + +Allowed the pure Python implementation of :class:`datetime.timezone` to +represent sub-minute offsets close to minimum and maximum boundaries, +specifically in the ranges (23:59, 24:00) and (-23:59, 24:00). Patch by +Ngalim Siregar + +.. + +.. bpo: 16970 +.. date: 2019-07-19-01-46-56 +.. nonce: GEASf5 +.. section: Library + +Adding a value error when an invalid value in passed to nargs Patch by +Robert Leenders + +.. + +.. bpo: 37587 +.. date: 2019-07-13-16-02-48 +.. nonce: fd-1aF +.. section: Library + +Make json.loads faster for long strings. (Patch by Marco Paolini) + +.. + +.. bpo: 18378 +.. date: 2019-07-13-13-40-12 +.. nonce: NHcojp +.. section: Library + +Recognize "UTF-8" as a valid value for LC_CTYPE in locale._parse_localename. + +.. + +.. bpo: 37531 +.. date: 2019-07-09-19-38-26 +.. nonce: GX7s8S +.. section: Library + +"python3 -m test -jN --timeout=TIMEOUT" now kills a worker process if it +runs longer than *TIMEOUT* seconds. + +.. + +.. bpo: 37482 +.. date: 2019-07-09-11-20-21 +.. nonce: auzvev +.. section: Library + +Fix serialization of display name in originator or destination address +fields with both encoded words and special chars. + +.. + +.. bpo: 37372 +.. date: 2019-06-22-12-30-00 +.. nonce: kIKqZ6 +.. section: Library + +Fix error unpickling datetime.time objects from Python 2 with seconds>=24. +Patch by Justin Blanchard. + +.. + +.. bpo: 37085 +.. date: 2019-06-18-16-29-31 +.. nonce: GeYaD6 +.. section: Library + +Add the optional Linux SocketCAN Broadcast Manager constants, used as flags +to configure the BCM behaviour, in the socket module. Patch by Karl Ding. + +.. + +.. bpo: 36871 +.. date: 2019-05-12-12-58-37 +.. nonce: 6xiEHZ +.. section: Library + +Ensure method signature is used instead of constructor signature of a class +while asserting mock object against method calls. Patch by Karthikeyan +Singaravelan. + +.. + +.. bpo: 36582 +.. date: 2019-05-07-17-42-36 +.. nonce: L_dxR6 +.. section: Library + +Fix ``UserString.encode()`` to correctly return ``bytes`` rather than a +``UserString`` instance. + +.. + +.. bpo: 34775 +.. date: 2018-09-23-03-18-52 +.. nonce: vHeuHk +.. section: Library + +Division handling of PurePath now returns NotImplemented instead of raising +a TypeError when passed something other than an instance of str or PurePath. +Patch by Roger Aiudi. + +.. + +.. bpo: 37979 +.. date: 2019-08-29-10-40-05 +.. nonce: TAUx_E +.. section: Documentation + +Added a link to dateutil.parser.isoparse in the datetime.fromisoformat +documentation. Patch by Paul Ganssle + +.. + +.. bpo: 37759 +.. date: 2019-08-04-19-20-58 +.. nonce: EHRF4i +.. section: Documentation + +Beginning edits to Whatsnew 3.8 + +.. + +.. bpo: 37726 +.. date: 2019-07-31-11-40-06 +.. nonce: h-3o9a +.. section: Documentation + +Stop recommending getopt in the tutorial for command line argument parsing +and promote argparse. + +.. + +.. bpo: 37256 +.. date: 2019-07-16-14-48-12 +.. nonce: qJTrBb +.. section: Documentation + +Fix wording of arguments for :class:`Request` in :mod:`urllib.request` + +.. + +.. bpo: 37004 +.. date: 2019-05-22-04-30-07 +.. nonce: BRgxrt +.. section: Documentation + +In the documentation for difflib, a note was added explicitly warning that +the results of SequenceMatcher's ratio method may depend on the order of the +input strings. + +.. + +.. bpo: 36487 +.. date: 2019-04-02-19-23-00 +.. nonce: Jg6-MG +.. section: Documentation + +Make C-API docs clear about what the "main" interpreter is. + +.. + +.. bpo: 37805 +.. date: 2019-08-25-19-51-46 +.. nonce: Kl1sti +.. section: Tests + +Add tests for json.dump(..., skipkeys=True). Patch by Dong-hee Na. + +.. + +.. bpo: 37707 +.. date: 2019-07-29-11-36-16 +.. nonce: Sm-dGk +.. section: Build + +Mark some individual tests to skip when --pgo is used. The tests marked +increase the PGO task time significantly and likely don't help improve +optimization of the final executable. + +.. + +.. bpo: 37549 +.. date: 2019-08-22-09-04-44 +.. nonce: TpKI3M +.. section: Windows + +:func:`os.dup` no longer fails for standard streams on Windows 7. + +.. + +.. bpo: 1311 +.. date: 2019-08-21-12-58-18 +.. nonce: BoW1wU +.. section: Windows + +The ``nul`` file on Windows now returns True from :func:`~os.path.exists` +and a valid result from :func:`os.stat` with ``S_IFCHR`` set. + +.. + +.. bpo: 9949 +.. date: 2019-08-14-13-40-15 +.. nonce: zW45Ks +.. section: Windows + +Enable support for following symlinks in :func:`os.realpath`. + +.. + +.. bpo: 37834 +.. date: 2019-08-12-12-00-24 +.. nonce: VB2QVj +.. section: Windows + +Treat all name surrogate reparse points on Windows in :func:`os.lstat` and +other reparse points as regular files in :func:`os.stat`. + +.. + +.. bpo: 36266 +.. date: 2019-08-08-18-05-27 +.. nonce: x4eZU3 +.. section: Windows + +Add the module name in the formatted error message when DLL load fail +happens during module import in ``_PyImport_FindSharedFuncptrWindows()``. +Patch by Srinivas Nyayapati. + +.. + +.. bpo: 25172 +.. date: 2019-08-06-18-09-18 +.. nonce: Akreij +.. section: Windows + +Trying to import the :mod:`crypt` module on Windows will result in an +:exc:`ImportError` with a message explaining that the module isn't supported +on Windows. On other platforms, if the underlying ``_crypt`` module is not +available, the ImportError will include a message explaining the problem. + +.. + +.. bpo: 37778 +.. date: 2019-08-06-13-54-12 +.. nonce: AY1XhH +.. section: Windows + +Fixes the icons used for file associations to the Microsoft Store package. + +.. + +.. bpo: 37734 +.. date: 2019-08-06-09-35-12 +.. nonce: EoJ9Nh +.. section: Windows + +Fix use of registry values to launch Python from Microsoft Store app. + +.. + +.. bpo: 28269 +.. date: 2019-05-05-05-23-34 +.. nonce: -MOHI7 +.. section: Windows + +Replace use of :c:func:`strcasecmp` for the system function +:c:func:`_stricmp`. Patch by Minmin Gong. + +.. + +.. bpo: 18049 +.. date: 2019-07-13-15-58-18 +.. nonce: MklhQQ +.. section: macOS + +Increase the default stack size of threads from 5MB to 16MB on macOS, to +match the stack size of the main thread. This avoids crashes on deep +recursion in threads. + +.. + +.. bpo: 37824 +.. date: 2019-08-26-00-41-53 +.. nonce: YY5jAI +.. section: IDLE + +Properly handle user input warnings in IDLE shell. Cease turning +SyntaxWarnings into SyntaxErrors. + +.. + +.. bpo: 37929 +.. date: 2019-08-24-22-00-33 +.. nonce: jb7523 +.. section: IDLE + +IDLE Settings dialog now closes properly when there is no shell window. + +.. + +.. bpo: 37849 +.. date: 2019-08-14-09-43-15 +.. nonce: -bcYF3 +.. section: IDLE + +Fixed completions list appearing too high or low when shown above the +current line. + +.. + +.. bpo: 36419 +.. date: 2019-08-04-17-10-01 +.. nonce: TJZqOc +.. section: IDLE + +Refactor IDLE autocomplete and improve testing. + +.. + +.. bpo: 37748 +.. date: 2019-08-04-15-27-50 +.. nonce: 0vf6pg +.. section: IDLE + +Reorder the Run menu. Put the most common choice, Run Module, at the top. + +.. + +.. bpo: 37942 +.. date: 2019-08-24-12-11-30 +.. nonce: 7H8N9a +.. section: Tools/Demos + +Improve ArgumentClinic converter for floats. + +.. + +.. bpo: 37034 +.. date: 2019-05-27-16-13-08 +.. nonce: zbTgy8 +.. section: Tools/Demos + +Argument Clinic now uses the argument name on errors with keyword-only +argument instead of their position. Patch contributed by Rémi Lapeyre. + +.. + +.. bpo: 36763 +.. date: 2019-08-23-18-45-11 +.. nonce: q3Kh8Z +.. section: C API + +Options added by ``PySys_AddXOption()`` are now handled the same way than +``PyConfig.xoptions`` and command line ``-X`` options. + +.. + +.. bpo: 37926 +.. date: 2019-08-23-11-35-55 +.. nonce: hnI5IQ +.. section: C API + +Fix a crash in ``PySys_SetArgvEx(0, NULL, 0)``. diff --git a/Misc/NEWS.d/3.8.0rc1.rst b/Misc/NEWS.d/3.8.0rc1.rst new file mode 100644 index 00000000000000..f7c3c9984c09e1 --- /dev/null +++ b/Misc/NEWS.d/3.8.0rc1.rst @@ -0,0 +1,1349 @@ +.. bpo: 38243 +.. date: 2019-09-25-13-21-09 +.. nonce: 1pfz24 +.. release date: 2019-10-01 +.. section: Security + +Escape the server title of :class:`xmlrpc.server.DocXMLRPCServer` when +rendering the document page as HTML. (Contributed by Dong-hee Na in +:issue:`38243`.) + +.. + +.. bpo: 38174 +.. date: 2019-09-23-21-02-46 +.. nonce: MeWuJd +.. section: Security + +Update vendorized expat library version to 2.2.8, which resolves +CVE-2019-15903. + +.. + +.. bpo: 37764 +.. date: 2019-08-27-01-13-05 +.. nonce: qv67PQ +.. section: Security + +Fixes email._header_value_parser.get_unstructured going into an infinite +loop for a specific case in which the email header does not have trailing +whitespace, and the case in which it contains an invalid encoded word. Patch +by Ashwin Ramaswami. + +.. + +.. bpo: 38006 +.. date: 2019-09-30-09-33-21 +.. nonce: UYlJum +.. section: Core and Builtins + +Fix a bug due to the interaction of weakrefs and the cyclic garbage +collector. We must clear any weakrefs in garbage in order to prevent their +callbacks from executing and causing a crash. + +.. + +.. bpo: 38317 +.. date: 2019-09-30-00-56-21 +.. nonce: pmqlIQ +.. section: Core and Builtins + +Fix warnings options priority: ``PyConfig.warnoptions`` has the highest +priority, as stated in the :pep:`587`. + +.. + +.. bpo: 36871 +.. date: 2019-09-24-18-45-46 +.. nonce: p47knk +.. section: Core and Builtins + +Improve error handling for the assert_has_calls and assert_has_awaits +methods of mocks. Fixed a bug where any errors encountered while binding the +expected calls to the mock's spec were silently swallowed, leading to +misleading error output. + +.. + +.. bpo: 38236 +.. date: 2019-09-20-19-06-23 +.. nonce: eQ0Tmj +.. section: Core and Builtins + +Python now dumps path configuration if it fails to import the Python codecs +of the filesystem and stdio encodings. + +.. + +.. bpo: 38013 +.. date: 2019-09-12-19-50-01 +.. nonce: I7btD0 +.. section: Core and Builtins + +Allow to call ``async_generator_athrow().throw(...)`` even for non-started +async generator helper. It fixes annoying warning at the end of +:func:`asyncio.run` call. + +.. + +.. bpo: 38124 +.. date: 2019-09-12-00-14-01 +.. nonce: n6E0H7 +.. section: Core and Builtins + +Fix an off-by-one error in PyState_AddModule that could cause out-of-bounds +memory access. + +.. + +.. bpo: 38005 +.. date: 2019-09-02-20-00-31 +.. nonce: e7VsTA +.. section: Core and Builtins + +Fixed comparing and creating of InterpreterID and ChannelID. + +.. + +.. bpo: 37994 +.. date: 2019-08-31-11-13-25 +.. nonce: Rj6S4j +.. section: Core and Builtins + +Fixed silencing arbitrary errors if an attribute lookup fails in several +sites. Only AttributeError should be silenced. + +.. + +.. bpo: 37990 +.. date: 2019-08-31-09-22-33 +.. nonce: WDY2f- +.. section: Core and Builtins + +Fix elapsed time in gc stats was not printed correctly. This bug was a +regression in 3.8b4. + +.. + +.. bpo: 37966 +.. date: 2019-08-27-21-21-36 +.. nonce: 5OBLez +.. section: Core and Builtins + +The implementation of :func:`~unicodedata.is_normalized` has been greatly +sped up on strings that aren't normalized, by implementing the full +normalization-quick-check algorithm from the Unicode standard. + +.. + +.. bpo: 20490 +.. date: 2019-08-15-12-48-36 +.. nonce: -hXeEn +.. section: Core and Builtins + +Improve import error message for partially initialized module on circular +``from`` imports - by Anthony Sottile. + +.. + +.. bpo: 37409 +.. date: 2019-08-06-23-39-05 +.. nonce: 1qwzn2 +.. section: Core and Builtins + +Ensure explicit relative imports from interactive sessions and scripts +(having no parent package) always raise ImportError, rather than treating +the current module as the package. Patch by Ben Lewis. + +.. + +.. bpo: 37619 +.. date: 2019-07-18-11-50-49 +.. nonce: X6Lulo +.. section: Core and Builtins + +When adding a wrapper descriptor from one class to a different class (for +example, setting ``__add__ = str.__add__`` on an ``int`` subclass), an +exception is correctly raised when the operator is called. + +.. + +.. bpo: 30773 +.. date: 2018-06-07-01-01-20 +.. nonce: C31rVE +.. section: Core and Builtins + +Prohibit parallel running of aclose() / asend() / athrow(). Fix ag_running +to reflect the actual running status of the AG. + +.. + +.. bpo: 38319 +.. date: 2019-09-30-22-06-33 +.. nonce: 5QjiDa +.. section: Library + +sendfile() used in socket and shutil modules was raising OverflowError for +files >= 2GiB on 32-bit architectures. (patch by Giampaolo Rodola) + +.. + +.. bpo: 38242 +.. date: 2019-09-30-00-15-27 +.. nonce: uPIyAc +.. section: Library + +Revert the new asyncio Streams API + +.. + +.. bpo: 38019 +.. date: 2019-09-29-13-50-24 +.. nonce: 6MoOE3 +.. section: Library + +Correctly handle pause/resume reading of closed asyncio unix pipe. + +.. + +.. bpo: 38163 +.. date: 2019-09-28-20-16-40 +.. nonce: x51-vK +.. section: Library + +Child mocks will now detect their type as either synchronous or +asynchronous, asynchronous child mocks will be AsyncMocks and synchronous +child mocks will be either MagicMock or Mock (depending on their parent +type). + +.. + +.. bpo: 38161 +.. date: 2019-09-27-16-31-28 +.. nonce: zehai1 +.. section: Library + +Removes _AwaitEvent from AsyncMock. + +.. + +.. bpo: 38216 +.. date: 2019-09-27-15-24-45 +.. nonce: -7yvZR +.. section: Library + +Allow the rare code that wants to send invalid http requests from the +`http.client` library a way to do so. The fixes for bpo-30458 led to +breakage for some projects that were relying on this ability to test their +own behavior in the face of bad requests. + +.. + +.. bpo: 38108 +.. date: 2019-09-25-21-37-02 +.. nonce: Jr9HU6 +.. section: Library + +Any synchronous magic methods on an AsyncMock now return a MagicMock. Any +asynchronous magic methods on a MagicMock now return an AsyncMock. + +.. + +.. bpo: 38248 +.. date: 2019-09-22-13-05-36 +.. nonce: Yo3N_1 +.. section: Library + +asyncio: Fix inconsistent immediate Task cancellation + +.. + +.. bpo: 38237 +.. date: 2019-09-20-14-27-17 +.. nonce: xRUZbx +.. section: Library + +The arguments for the builtin pow function are more descriptive. They can +now also be passed in as keywords. + +.. + +.. bpo: 38191 +.. date: 2019-09-17-12-28-27 +.. nonce: 1TU0HV +.. section: Library + +Constructors of :class:`~typing.NamedTuple` and :class:`~typing.TypedDict` +types now accept arbitrary keyword argument names, including "cls", "self", +"typename", "_typename", "fields" and "_fields". Passing positional +arguments by keyword is deprecated. + +.. + +.. bpo: 38185 +.. date: 2019-09-16-19-12-57 +.. nonce: zYWppY +.. section: Library + +Fixed case-insensitive string comparison in :class:`sqlite3.Row` indexing. + +.. + +.. bpo: 38136 +.. date: 2019-09-16-09-54-42 +.. nonce: MdI-Zb +.. section: Library + +Changes AsyncMock call count and await count to be two different counters. +Now await count only counts when a coroutine has been awaited, not when it +has been called, and vice-versa. Update the documentation around this. + +.. + +.. bpo: 37828 +.. date: 2019-09-15-21-31-18 +.. nonce: gLLDX7 +.. section: Library + +Fix default mock name in :meth:`unittest.mock.Mock.assert_called` +exceptions. Patch by Abraham Toriz Cruz. + +.. + +.. bpo: 38175 +.. date: 2019-09-15-10-30-33 +.. nonce: 61XlUv +.. section: Library + +Fix a memory leak in comparison of :class:`sqlite3.Row` objects. + +.. + +.. bpo: 33936 +.. date: 2019-09-14-10-34-00 +.. nonce: 8wCI_n +.. section: Library + +_hashlib no longer calls obsolete OpenSSL initialization function with +OpenSSL 1.1.0+. + +.. + +.. bpo: 34706 +.. date: 2019-09-13-14-54-33 +.. nonce: HWVpOY +.. section: Library + +Preserve subclassing in inspect.Signature.from_callable. + +.. + +.. bpo: 38153 +.. date: 2019-09-13-12-18-51 +.. nonce: nHAbuJ +.. section: Library + +Names of hashing algorithms frome OpenSSL are now normalized to follow +Python's naming conventions. For example OpenSSL uses sha3-512 instead of +sha3_512 or blake2b512 instead of blake2b. + +.. + +.. bpo: 38115 +.. date: 2019-09-13-09-24-58 +.. nonce: BOO-Y1 +.. section: Library + +Fix a bug in dis.findlinestarts() where it would return invalid bytecode +offsets. Document that a code object's co_lnotab can contain invalid +bytecode offsets. + +.. + +.. bpo: 38148 +.. date: 2019-09-13-08-55-43 +.. nonce: Lnww6D +.. section: Library + +Add slots to :mod:`asyncio` transport classes, which can reduce memory +usage. + +.. + +.. bpo: 36991 +.. date: 2019-09-12-14-52-38 +.. nonce: 1OcSm8 +.. section: Library + +Fixes a potential incorrect AttributeError exception escaping +ZipFile.extract() in some unsupported input error situations. + +.. + +.. bpo: 38134 +.. date: 2019-09-12-13-18-55 +.. nonce: gXJTbP +.. section: Library + +Remove obsolete copy of PBKDF2_HMAC_fast. All supported OpenSSL versions +contain a fast implementation. + +.. + +.. bpo: 38132 +.. date: 2019-09-12-12-47-35 +.. nonce: KSFx1F +.. section: Library + +The OpenSSL hashlib wrapper uses a simpler implementation. Several Macros +and pointless caches are gone. The hash name now comes from OpenSSL's EVP. +The algorithm name stays the same, except it is now always lower case. + +.. + +.. bpo: 38008 +.. date: 2019-09-12-10-47-34 +.. nonce: sH74Iy +.. section: Library + +Fix parent class check in protocols to correctly identify the module that +provides a builtin protocol, instead of assuming they all come from the +:mod:`collections.abc` module + +.. + +.. bpo: 37405 +.. date: 2019-09-11-20-27-41 +.. nonce: MG5xiY +.. section: Library + +Fixed regression bug for socket.getsockname() for non-CAN_ISOTP AF_CAN +address family sockets by returning a 1-tuple instead of string. + +.. + +.. bpo: 38121 +.. date: 2019-09-11-16-54-57 +.. nonce: SrSDzB +.. section: Library + +Update parameter names on functions in importlib.metadata matching the +changes in the 0.22 release of importlib_metadata. + +.. + +.. bpo: 38110 +.. date: 2019-09-11-14-49-20 +.. nonce: A19Y-q +.. section: Library + +The os.closewalk() implementation now uses the libc fdwalk() API on +platforms where it is available. + +.. + +.. bpo: 38093 +.. date: 2019-09-11-14-45-30 +.. nonce: yQ6k7y +.. section: Library + +Fixes AsyncMock so it doesn't crash when used with AsyncContextManagers or +AsyncIterators. + +.. + +.. bpo: 37488 +.. date: 2019-09-11-11-44-16 +.. nonce: S8CJUL +.. section: Library + +Add warning to :meth:`datetime.utctimetuple`, :meth:`datetime.utcnow` and +:meth:`datetime.utcfromtimestamp` . + +.. + +.. bpo: 38086 +.. date: 2019-09-10-11-42-59 +.. nonce: w5TlG- +.. section: Library + +Update importlib.metadata with changes from `importlib_metadata 0.21 +`_. + +.. + +.. bpo: 37251 +.. date: 2019-09-10-10-59-50 +.. nonce: 8zn2o3 +.. section: Library + +Remove `__code__` check in AsyncMock that incorrectly evaluated function +specs as async objects but failed to evaluate classes with `__await__` but +no `__code__` attribute defined as async objects. + +.. + +.. bpo: 38037 +.. date: 2019-09-09-18-39-23 +.. nonce: B0UgFU +.. section: Library + +Fix reference counters in the :mod:`signal` module. + +.. + +.. bpo: 38066 +.. date: 2019-09-09-14-39-47 +.. nonce: l9mWv- +.. section: Library + +Hide internal asyncio.Stream methods: feed_eof(), feed_data(), +set_exception() and set_transport(). + +.. + +.. bpo: 38059 +.. date: 2019-09-08-11-36-50 +.. nonce: 8SA6co +.. section: Library + +inspect.py now uses sys.exit() instead of exit() + +.. + +.. bpo: 37953 +.. date: 2019-09-06-17-40-34 +.. nonce: db5FQq +.. section: Library + +In :mod:`typing`, improved the ``__hash__`` and ``__eq__`` methods for +:class:`ForwardReferences`. + +.. + +.. bpo: 38026 +.. date: 2019-09-04-20-34-14 +.. nonce: 0LLRX- +.. section: Library + +Fixed :func:`inspect.getattr_static` used ``isinstance`` while it should +avoid dynamic lookup. + +.. + +.. bpo: 38010 +.. date: 2019-09-02-14-30-39 +.. nonce: JOnz9Z +.. section: Library + +In ``importlib.metadata`` sync with ``importlib_metadata`` 0.20, clarifying +behavior of ``files()`` and fixing issue where only one requirement was +returned for ``requires()`` on ``dist-info`` packages. + +.. + +.. bpo: 38006 +.. date: 2019-09-02-13-37-27 +.. nonce: Y7vA0Q +.. section: Library + +weakref.WeakValueDictionary defines a local remove() function used as +callback for weak references. This function was created with a closure. +Modify the implementation to avoid the closure. + +.. + +.. bpo: 34410 +.. date: 2019-08-31-01-52-59 +.. nonce: 7KbWZQ +.. section: Library + +Fixed a crash in the :func:`tee` iterator when re-enter it. RuntimeError is +now raised in this case. + +.. + +.. bpo: 37140 +.. date: 2019-08-30-11-21-10 +.. nonce: cFAX-a +.. section: Library + +Fix a ctypes regression of Python 3.8. When a ctypes.Structure is passed by +copy to a function, ctypes internals created a temporary object which had +the side effect of calling the structure finalizer (__del__) twice. The +Python semantics requires a finalizer to be called exactly once. Fix ctypes +internals to no longer call the finalizer twice. + +.. + +.. bpo: 37972 +.. date: 2019-08-28-21-40-12 +.. nonce: kP-n4L +.. section: Library + +Subscripts to the `unittest.mock.call` objects now receive the same chaining +mechanism as any other custom attributes, so that the following usage no +longer raises a `TypeError`: + +call().foo().__getitem__('bar') + +Patch by blhsing + +.. + +.. bpo: 22347 +.. date: 2019-08-27-01-03-26 +.. nonce: _TRpYr +.. section: Library + +Update mimetypes.guess_type to allow proper parsing of URLs with only a host +name. Patch by Dong-hee Na. + +.. + +.. bpo: 37885 +.. date: 2019-08-19-10-31-41 +.. nonce: 4Nc9sp +.. section: Library + +venv: Don't generate unset variable warning on deactivate. + +.. + +.. bpo: 37785 +.. date: 2019-08-07-14-49-22 +.. nonce: y7OlT8 +.. section: Library + +Fix xgettext warnings in :mod:`argparse`. + +.. + +.. bpo: 11953 +.. date: 2019-07-29-21-39-45 +.. nonce: 4Hpwf9 +.. section: Library + +Completing WSA* error codes in :mod:`socket`. + +.. + +.. bpo: 37424 +.. date: 2019-07-04-13-00-20 +.. nonce: 0i1MR- +.. section: Library + +Fixes a possible hang when using a timeout on `subprocess.run()` while +capturing output. If the child process spawned its own children or +otherwise connected its stdout or stderr handles with another process, we +could hang after the timeout was reached and our child was killed when +attempting to read final output from the pipes. + +.. + +.. bpo: 37212 +.. date: 2019-06-22-22-00-35 +.. nonce: Zhv-tq +.. section: Library + +:func:`unittest.mock.call` now preserves the order of keyword arguments in +repr output. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 37305 +.. date: 2019-06-18-13-59-55 +.. nonce: fGzWlP +.. section: Library + +Add .webmanifest -> application/manifest+json to list of recognized file +types and content type headers + +.. + +.. bpo: 21872 +.. date: 2019-06-12-08-56-22 +.. nonce: V9QGGN +.. section: Library + +Fix :mod:`lzma`: module decompresses data incompletely. When decompressing a +FORMAT_ALONE format file, and it doesn't have the end marker, sometimes the +last one to dozens bytes can't be output. Patch by Ma Lin. + +.. + +.. bpo: 37206 +.. date: 2019-06-09-22-25-03 +.. nonce: 2WBg4q +.. section: Library + +Default values which cannot be represented as Python objects no longer +improperly represented as ``None`` in function signatures. + +.. + +.. bpo: 12144 +.. date: 2019-06-08-23-26-58 +.. nonce: Z7mz-q +.. section: Library + +Ensure cookies with ``expires`` attribute are handled in +:meth:`CookieJar.make_cookies`. + +.. + +.. bpo: 31163 +.. date: 2019-05-26-16-34-53 +.. nonce: 21A802 +.. section: Library + +pathlib.Path instance's rename and replace methods now return the new Path +instance. + +.. + +.. bpo: 25068 +.. date: 2019-05-22-04-52-35 +.. nonce: vR_rC- +.. section: Library + +:class:`urllib.request.ProxyHandler` now lowercases the keys of the passed +dictionary. + +.. + +.. bpo: 21315 +.. date: 2019-05-19-10-48-46 +.. nonce: PgXVqF +.. section: Library + +Email headers containing RFC2047 encoded words are parsed despite the +missing whitespace, and a defect registered. Also missing trailing +whitespace after encoded words is now registered as a defect. + +.. + +.. bpo: 36250 +.. date: 2019-03-09-16-04-12 +.. nonce: tSK4N1 +.. section: Library + +Ignore ``ValueError`` from ``signal`` with ``interaction`` in non-main +thread. + +.. + +.. bpo: 35168 +.. date: 2019-01-22-09-23-20 +.. nonce: UGv2yW +.. section: Library + +:attr:`shlex.shlex.punctuation_chars` is now a read-only property. + +.. + +.. bpo: 20504 +.. date: 2018-11-21-18-05-50 +.. nonce: kG0ub5 +.. section: Library + +Fixes a bug in :mod:`cgi` module when a multipart/form-data request has no +`Content-Length` header. + +.. + +.. bpo: 34519 +.. date: 2018-08-27-15-44-50 +.. nonce: cPlH1h +.. section: Library + +Add additional aliases for HP Roman 8. Patch by Michael Osipov. + +.. + +.. bpo: 26868 +.. date: 2019-09-07-15-55-46 +.. nonce: Raw0Gd +.. section: Documentation + +Fix example usage of :c:func:`PyModule_AddObject` to properly handle errors. + +.. + +.. bpo: 36797 +.. date: 2019-09-05-14-47-51 +.. nonce: KN9Ga5 +.. section: Documentation + +Fix a dead link in the distutils API Reference. + +.. + +.. bpo: 37977 +.. date: 2019-08-29-14-38-01 +.. nonce: pML-UI +.. section: Documentation + +Warn more strongly and clearly about pickle insecurity + +.. + +.. bpo: 37937 +.. date: 2019-08-24-12-59-06 +.. nonce: F7fHbt +.. section: Documentation + +Mention ``frame.f_trace`` in :func:`sys.settrace` docs. + +.. + +.. bpo: 36260 +.. date: 2019-06-04-09-29-00 +.. nonce: WrGuc- +.. section: Documentation + +Add decompression pitfalls to zipfile module documentation. + +.. + +.. bpo: 36960 +.. date: 2019-05-18-16-25-44 +.. nonce: xEKHXj +.. section: Documentation + +Restructured the :mod:`datetime` docs in the interest of making them more +user-friendly and improving readability. Patch by Brad Solomon. + +.. + +.. bpo: 23460 +.. date: 2019-02-14-07-12-48 +.. nonce: Iqiqtm +.. section: Documentation + +The documentation for decimal string formatting using the `:g` specifier has +been updated to reflect the correct exponential notation cutoff point. +Original patch contributed by Tuomas Suutari. + +.. + +.. bpo: 35803 +.. date: 2019-01-21-14-30-59 +.. nonce: yae6Lq +.. section: Documentation + +Document and test that ``tempfile`` functions may accept a :term:`path-like +object` for the ``dir`` argument. Patch by Anthony Sottile. + +.. + +.. bpo: 33944 +.. date: 2018-10-26-18-10-29 +.. nonce: V1YeOA +.. section: Documentation + +Added a note about the intended use of code in .pth files. + +.. + +.. bpo: 34293 +.. date: 2018-07-31-15-38-26 +.. nonce: yHupAL +.. section: Documentation + +Fix the Doc/Makefile regarding PAPER environment variable and PDF builds + +.. + +.. bpo: 38239 +.. date: 2019-09-26-15-48-36 +.. nonce: MfoVzY +.. section: Tests + +Fix test_gdb for Link Time Optimization (LTO) builds. + +.. + +.. bpo: 38275 +.. date: 2019-09-25-14-40-57 +.. nonce: -kdveI +.. section: Tests + +test_ssl now handles disabled TLS/SSL versions better. OpenSSL's crypto +policy and run-time settings are recognized and tests for disabled versions +are skipped. Tests also accept more TLS minimum_versions for platforms that +override OpenSSL's default with strict settings. + +.. + +.. bpo: 38271 +.. date: 2019-09-25-13-11-29 +.. nonce: iHXNIg +.. section: Tests + +The private keys for test_ssl were encrypted with 3DES in traditional PKCS#5 +format. 3DES and the digest algorithm of PKCS#5 are blocked by some strict +crypto policies. Use PKCS#8 format with AES256 encryption instead. + +.. + +.. bpo: 38270 +.. date: 2019-09-25-12-18-31 +.. nonce: _x-9uH +.. section: Tests + +test.support now has a helper function to check for availibility of a hash +digest function. Several tests are refactored avoid MD5 and use SHA256 +instead. Other tests are marked to use MD5 and skipped when MD5 is disabled. + +.. + +.. bpo: 37123 +.. date: 2019-09-24-12-30-55 +.. nonce: IoutBn +.. section: Tests + +Multiprocessing test test_mymanager() now also expects -SIGTERM, not only +exitcode 0. BaseManager._finalize_manager() sends SIGTERM to the manager +process if it takes longer than 1 second to stop, which happens on slow +buildbots. + +.. + +.. bpo: 38212 +.. date: 2019-09-24-12-24-05 +.. nonce: IWbhWz +.. section: Tests + +Multiprocessing tests: increase test_queue_feeder_donot_stop_onexc() timeout +from 1 to 60 seconds. + +.. + +.. bpo: 38117 +.. date: 2019-09-11-17-22-32 +.. nonce: X7LgGY +.. section: Tests + +Test with OpenSSL 1.1.1d + +.. + +.. bpo: 37531 +.. date: 2019-08-20-19-24-19 +.. nonce: wRoXfU +.. section: Tests + +Enhance regrtest multiprocess timeout: write a message when killing a worker +process, catch popen.kill() and popen.wait() exceptions, put a timeout on +the second call to popen.communicate(). + +.. + +.. bpo: 37876 +.. date: 2019-08-16-16-15-14 +.. nonce: m3k1w3 +.. section: Tests + +Add tests for ROT-13 codec. + +.. + +.. bpo: 37252 +.. date: 2019-06-12-14-30-29 +.. nonce: 4o-uLs +.. section: Tests + +Fix assertions in ``test_close`` and ``test_events_mask_overflow`` devpoll +tests. + +.. + +.. bpo: 34001 +.. date: 2019-06-03-20-47-10 +.. nonce: KvYx9z +.. section: Tests + +Make test_ssl pass with LibreSSL. LibreSSL handles minimum and maximum TLS +version differently than OpenSSL. + +.. + +.. bpo: 36919 +.. date: 2019-05-28-15-41-34 +.. nonce: -vGt_m +.. section: Tests + +Make ``test_source_encoding.test_issue2301`` implementation independent. The +test will work now for both CPython and IronPython. + +.. + +.. bpo: 34596 +.. date: 2018-09-07-01-18-27 +.. nonce: r2-EGd +.. section: Tests + +Fallback to a default reason when :func:`unittest.skip` is uncalled. Patch +by Naitree Zhu. + +.. + +.. bpo: 38301 +.. date: 2019-09-28-02-37-11 +.. nonce: 123456 +.. section: Build + +In Solaris family, we must be sure to use ``-D_REENTRANT``. Patch by Jesús +Cea Avión. + +.. + +.. bpo: 36210 +.. date: 2019-09-24-22-47-47 +.. nonce: EmL9X1 +.. section: Build + +Update optional extension module detection for AIX. ossaudiodev and spwd are +not applicable for AIX, and are no longer reported as missing. 3rd-party +packaging of ncurses (with ASIS support) conflicts with officially supported +AIX curses library, so configure AIX to use libcurses.a. However, skip +trying to build _curses_panel. + +patch by M Felt + +.. + +.. bpo: 36002 +.. date: 2019-09-13-14-12-36 +.. nonce: Bcl4oe +.. section: Build + +Locate ``llvm-profdata`` and ``llvm-ar`` binaries using ``AC_PATH_TOOL`` +rather than ``AC_PATH_TARGET_TOOL``. + +.. + +.. bpo: 37936 +.. date: 2019-09-10-00-54-48 +.. nonce: E7XEwu +.. section: Build + +The :file:`.gitignore` file systematically keeps "rooted", with a +non-trailing slash, all the rules that are meant to apply to files in a +specific place in the repo. Previously, when the intended file to ignore +happened to be at the root of the repo, we'd most often accidentally also +ignore files and directories with the same name anywhere in the tree. + +.. + +.. bpo: 37936 +.. date: 2019-08-24-00-29-40 +.. nonce: QrORqA +.. section: Build + +The :file:`.gitignore` file no longer applies to any files that are in fact +tracked in the Git repository. Patch by Greg Price. + +.. + +.. bpo: 38117 +.. date: 2019-09-16-14-07-11 +.. nonce: hJVf0C +.. section: Windows + +Update bundled OpenSSL to 1.1.1d + +.. + +.. bpo: 38092 +.. date: 2019-09-13-14-11-42 +.. nonce: x31ehI +.. section: Windows + +Reduce overhead when using multiprocessing in a Windows virtual environment. + +.. + +.. bpo: 38133 +.. date: 2019-09-12-12-05-55 +.. nonce: yFeRGS +.. section: Windows + +Allow py.exe launcher to locate installations from the Microsoft Store and +improve display of active virtual environments. + +.. + +.. bpo: 38114 +.. date: 2019-09-11-15-24-04 +.. nonce: cc0E5E +.. section: Windows + +The ``pip.ini`` is no longer included in the Nuget package. + +.. + +.. bpo: 36634 +.. date: 2019-09-11-14-42-04 +.. nonce: 8Un8ih +.. section: Windows + +:func:`os.cpu_count` now returns active processors rather than maximum +processors. + +.. + +.. bpo: 36634 +.. date: 2019-09-11-12-34-31 +.. nonce: xLaGgb +.. section: Windows + +venv activate.bat now works when the existing variables contain double quote +characters. + +.. + +.. bpo: 38081 +.. date: 2019-09-11-10-22-01 +.. nonce: 8JhzjD +.. section: Windows + +Prevent error calling :func:`os.path.realpath` on ``'NUL'``. + +.. + +.. bpo: 38087 +.. date: 2019-09-10-14-21-40 +.. nonce: --eIib +.. section: Windows + +Fix case sensitivity in test_pathlib and test_ntpath. + +.. + +.. bpo: 38088 +.. date: 2019-09-10-14-17-25 +.. nonce: FOvWSM +.. section: Windows + +Fixes distutils not finding vcruntime140.dll with only the v142 toolset +installed. + +.. + +.. bpo: 37283 +.. date: 2019-09-09-12-22-23 +.. nonce: 8NvOkU +.. section: Windows + +Ensure command-line and unattend.xml setting override previously detected +states in Windows installer. + +.. + +.. bpo: 38030 +.. date: 2019-09-04-14-01-08 +.. nonce: _USdtk +.. section: Windows + +Fixes :func:`os.stat` failing for block devices on Windows + +.. + +.. bpo: 38020 +.. date: 2019-09-03-11-47-37 +.. nonce: xFZ2j0 +.. section: Windows + +Fixes potential crash when calling :func:`os.readlink` (or indirectly +through :func:`~os.path.realpath`) on a file that is not a supported link. + +.. + +.. bpo: 37705 +.. date: 2019-08-30-15-15-22 +.. nonce: 2o4NWW +.. section: Windows + +Improve the implementation of ``winerror_to_errno()``. + +.. + +.. bpo: 37702 +.. date: 2019-07-29-16-49-31 +.. nonce: Lj2f5e +.. section: Windows + +Fix memory leak on Windows in creating an SSLContext object or running +urllib.request.urlopen('https://...'). + +.. + +.. bpo: 37445 +.. date: 2019-06-28-18-10-29 +.. nonce: LsdYO6 +.. section: Windows + +Include the ``FORMAT_MESSAGE_IGNORE_INSERTS`` flag in ``FormatMessageW()`` +calls. + +.. + +.. bpo: 37380 +.. date: 2019-06-25-04-15-22 +.. nonce: tPxjuz +.. section: Windows + +Don't collect unfinished processes with ``subprocess._active`` on Windows to +cleanup later. Patch by Ruslan Kuprieiev. + +.. + +.. bpo: 32587 +.. date: 2019-05-10-15-25-44 +.. nonce: -0g2O3 +.. section: Windows + +Make :data:`winreg.REG_MULTI_SZ` support zero-length strings. + +.. + +.. bpo: 38117 +.. date: 2019-09-15-21-29-13 +.. nonce: ZLsoAZ +.. section: macOS + +Updated OpenSSL to 1.1.1d in macOS installer. + +.. + +.. bpo: 38089 +.. date: 2019-09-10-14-24-35 +.. nonce: eedgyD +.. section: macOS + +Move Azure Pipelines to latest VM versions and make macOS tests optional + +.. + +.. bpo: 35379 +.. date: 2019-09-17-01-28-56 +.. nonce: yAECDr +.. section: IDLE + +When exiting IDLE, catch any AttributeError. One happens when +EditorWindow.close is called twice. Printing a traceback, when IDLE is run +from a terminal, is useless and annoying. + +.. + +.. bpo: 38183 +.. date: 2019-09-16-15-04-29 +.. nonce: eudCN1 +.. section: IDLE + +To avoid problems, test_idle ignores the user config directory. It no longer +tries to create or access .idlerc or any files within. Users must run IDLE +to discover problems with saving settings. + +.. + +.. bpo: 38077 +.. date: 2019-09-09-22-08-36 +.. nonce: Mzpfe2 +.. section: IDLE + +IDLE no longer adds 'argv' to the user namespace when initializing it. This +bug only affected 3.7.4 and 3.8.0b2 to 3.8.0b4. + +.. + +.. bpo: 38041 +.. date: 2019-09-05-23-12-13 +.. nonce: nxmGGK +.. section: IDLE + +Shell restart lines now fill the window width, always start with '=', and +avoid wrapping unnecessarily. The line will still wrap if the included file +name is long relative to the width. + +.. + +.. bpo: 35771 +.. date: 2019-09-01-10-22-55 +.. nonce: tdbmbP +.. section: IDLE + +To avoid occasional spurious test_idle failures on slower machines, increase +the ``hover_delay`` in test_tooltip. + +.. + +.. bpo: 37902 +.. date: 2019-08-21-16-02-49 +.. nonce: _R_adE +.. section: IDLE + +Add mousewheel scrolling for IDLE module, path, and stack browsers. Patch by +George Zhang. + +.. + +.. bpo: 37803 +.. date: 2019-09-12-16-15-55 +.. nonce: chEizy +.. section: Tools/Demos + +pdb's ``--help`` and ``--version`` long options now work. + +.. + +.. bpo: 37064 +.. date: 2019-05-27-15-26-12 +.. nonce: k_SPW2 +.. section: Tools/Demos + +Add option -k to pathscript.py script: preserve shebang flags. Add option -a +to pathscript.py script: add flags. + +.. + +.. bpo: 38234 +.. date: 2019-09-24-17-09-48 +.. nonce: d0bhEA +.. section: C API + +:c:func:`Py_SetPath` now sets :data:`sys.executable` to the program full +path (:c:func:`Py_GetProgramFullPath`) rather than to the program name +(:c:func:`Py_GetProgramName`). + +.. + +.. bpo: 38234 +.. date: 2019-09-20-17-22-41 +.. nonce: ZbquVK +.. section: C API + +Python ignored arguments passed to :c:func:`Py_SetPath`, +:c:func:`Py_SetPythonHome` and :c:func:`Py_SetProgramName`: fix Python +initialization to use specified arguments. + +.. + +.. bpo: 38205 +.. date: 2019-09-19-18-26-29 +.. nonce: Db1OJL +.. section: C API + +The :c:func:`Py_UNREACHABLE` macro now calls :c:func:`Py_FatalError`. + +.. + +.. bpo: 37879 +.. date: 2019-08-17-13-50-21 +.. nonce: CZeUem +.. section: C API + +Fix subtype_dealloc to suppress the type decref when the base type is a C +heap type diff --git a/Misc/NEWS.d/next/Build/2019-10-11-15-32-58.bpo-37415.D9RXrq.rst b/Misc/NEWS.d/next/Build/2019-10-11-15-32-58.bpo-37415.D9RXrq.rst new file mode 100644 index 00000000000000..98f4a3bf4f5457 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2019-10-11-15-32-58.bpo-37415.D9RXrq.rst @@ -0,0 +1,2 @@ +Fix stdatomic.h header check for ICC compiler: the ICC implementation lacks +atomic_uintptr_t type which is needed by Python. diff --git a/Misc/NEWS.d/next/C API/2019-10-07-17-15-09.bpo-36389.hFX_jD.rst b/Misc/NEWS.d/next/C API/2019-10-07-17-15-09.bpo-36389.hFX_jD.rst new file mode 100644 index 00000000000000..6c42882cdbaa60 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-10-07-17-15-09.bpo-36389.hFX_jD.rst @@ -0,0 +1,3 @@ +The ``_PyObject_CheckConsistency()`` function is now also available in release +mode. For example, it can be used to debug a crash in the ``visit_decref()`` +function of the GC. diff --git a/Misc/NEWS.d/next/C API/2019-10-21-09-24-03.bpo-38540.314N_T.rst b/Misc/NEWS.d/next/C API/2019-10-21-09-24-03.bpo-38540.314N_T.rst new file mode 100644 index 00000000000000..1d73ad8fe96e68 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-10-21-09-24-03.bpo-38540.314N_T.rst @@ -0,0 +1,3 @@ +Fixed possible leak in :c:func:`PyArg_Parse` and similar functions for +format units ``"es#"`` and ``"et#"`` when the macro +:c:macro:`PY_SSIZE_T_CLEAN` is not defined. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-20-00-36-18.bpo-38525.Vty1cA.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-20-00-36-18.bpo-38525.Vty1cA.rst new file mode 100644 index 00000000000000..c74d143762253d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-10-20-00-36-18.bpo-38525.Vty1cA.rst @@ -0,0 +1,2 @@ +Fix a segmentation fault when using reverse iterators of empty ``dict`` objects. +Patch by Dong-hee Na and Inada Naoki. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-20-12-43-48.bpo-38535.ESMkVN.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-20-12-43-48.bpo-38535.ESMkVN.rst new file mode 100644 index 00000000000000..7671fd06474ba5 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-10-20-12-43-48.bpo-38535.ESMkVN.rst @@ -0,0 +1,2 @@ +Fixed line numbers and column offsets for AST nodes for calls without +arguments in decorators. diff --git a/Misc/NEWS.d/next/Library/2017-12-26-14-32-23.bpo-27657.6BhyVK.rst b/Misc/NEWS.d/next/Library/2017-12-26-14-32-23.bpo-27657.6BhyVK.rst new file mode 100644 index 00000000000000..77746c0ce630ff --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-12-26-14-32-23.bpo-27657.6BhyVK.rst @@ -0,0 +1,2 @@ +Fix urllib.parse.urlparse() with numeric paths. A string like "path:80" is +no longer parsed as a path but as a scheme ("path") and a path ("80"). diff --git a/Misc/NEWS.d/next/Library/2018-04-24-13-18-48.bpo-33348.XaJDei.rst b/Misc/NEWS.d/next/Library/2018-04-24-13-18-48.bpo-33348.XaJDei.rst new file mode 100644 index 00000000000000..f95a73fb57ed41 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-24-13-18-48.bpo-33348.XaJDei.rst @@ -0,0 +1,2 @@ +lib2to3 now recognizes expressions after ``*`` and `**` like in ``f(*[] or +[])``. diff --git a/Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst b/Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst deleted file mode 100644 index 2d8c8b3222d099..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add parser for Message-ID header and add it to default HeaderRegistry. This -should prevent folding of Message-ID using RFC 2048 encoded words. diff --git a/Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst b/Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst deleted file mode 100644 index 019321d6f1d722..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed a bug in email parsing where a message with invalid bytes in -content-transfer-encoding of a multipart message can cause an AttributeError. -Patch by Andrew Donnellan. diff --git a/Misc/NEWS.d/next/Library/2019-10-15-09-47-40.bpo-33604.J12cWT.rst b/Misc/NEWS.d/next/Library/2019-10-15-09-47-40.bpo-33604.J12cWT.rst new file mode 100644 index 00000000000000..fbd73003cfcb64 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-15-09-47-40.bpo-33604.J12cWT.rst @@ -0,0 +1,3 @@ +Fixed `hmac.new` and `hmac.HMAC` to raise TypeError instead of ValueError +when the digestmod parameter, now required in 3.8, is omitted. Also +clarified the hmac module documentation and docstrings. diff --git a/Misc/NEWS.d/next/Library/2019-10-15-11-37-57.bpo-38478.A87OPO.rst b/Misc/NEWS.d/next/Library/2019-10-15-11-37-57.bpo-38478.A87OPO.rst new file mode 100644 index 00000000000000..b19fa23639d886 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-15-11-37-57.bpo-38478.A87OPO.rst @@ -0,0 +1,3 @@ +Fixed a bug in :meth:`inspect.signature.bind` that was causing it to fail +when handling a keyword argument with same name as positional-only parameter. +Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Library/2019-10-18-13-57-31.bpo-38521.U-7aaM.rst b/Misc/NEWS.d/next/Library/2019-10-18-13-57-31.bpo-38521.U-7aaM.rst new file mode 100644 index 00000000000000..9335bdc9545c4d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-18-13-57-31.bpo-38521.U-7aaM.rst @@ -0,0 +1 @@ +Fixed erroneous equality comparison in statistics.NormalDist(). diff --git a/Misc/NEWS.d/next/Library/2019-10-20-12-04-48.bpo-31202.NfdIus.rst b/Misc/NEWS.d/next/Library/2019-10-20-12-04-48.bpo-31202.NfdIus.rst new file mode 100644 index 00000000000000..8edb09d61317b3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-20-12-04-48.bpo-31202.NfdIus.rst @@ -0,0 +1,2 @@ +The case the result of :func:`pathlib.WindowsPath.glob` matches now the case +of the pattern for literal parts. diff --git a/Misc/NEWS.d/next/Library/2019-10-23-16-25-12.bpo-34679.Bnw8o3.rst b/Misc/NEWS.d/next/Library/2019-10-23-16-25-12.bpo-34679.Bnw8o3.rst new file mode 100644 index 00000000000000..34334db6032b5b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-23-16-25-12.bpo-34679.Bnw8o3.rst @@ -0,0 +1,2 @@ +asynci.ProactorEventLoop.close() now only calls signal.set_wakeup_fd() in the +main thread. diff --git a/Misc/NEWS.d/next/Security/2019-10-08-19-29-55.bpo-38418.QL7s0-.rst b/Misc/NEWS.d/next/Security/2019-10-08-19-29-55.bpo-38418.QL7s0-.rst new file mode 100644 index 00000000000000..b42a00047b96c0 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2019-10-08-19-29-55.bpo-38418.QL7s0-.rst @@ -0,0 +1 @@ +Fixes audit event for :func:`os.system` to be named ``os.system``. diff --git a/Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst b/Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst deleted file mode 100644 index 138a22f6acc249..00000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst +++ /dev/null @@ -1,2 +0,0 @@ -``test_venv.test_mutiprocessing()`` now explicitly calls -``pool.terminate()`` to wait until the pool completes. diff --git a/Misc/NEWS.d/next/Tests/2019-10-16-01-36-15.bpo-35998.G305Bf.rst b/Misc/NEWS.d/next/Tests/2019-10-16-01-36-15.bpo-35998.G305Bf.rst new file mode 100644 index 00000000000000..43d3942fd0772e --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-10-16-01-36-15.bpo-35998.G305Bf.rst @@ -0,0 +1,5 @@ +Fix a race condition in test_asyncio.test_start_tls_server_1(). Previously, +there was a race condition between the test main() function which replaces the +protocol and the test ServerProto protocol which sends ANSWER once it gets +HELLO. Now, only the test main() function is responsible to send data, +ServerProto no longer sends data. diff --git a/Misc/NEWS.d/next/Windows/2019-10-16-09-49-09.bpo-38492.Te1LxC.rst b/Misc/NEWS.d/next/Windows/2019-10-16-09-49-09.bpo-38492.Te1LxC.rst new file mode 100644 index 00000000000000..41fe695413f977 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2019-10-16-09-49-09.bpo-38492.Te1LxC.rst @@ -0,0 +1 @@ +Remove ``pythonw.exe`` dependency on the Microsoft C++ runtime. diff --git a/Misc/gdbinit b/Misc/gdbinit index afefe0818e4c77..45e79fcf6f4682 100644 --- a/Misc/gdbinit +++ b/Misc/gdbinit @@ -14,30 +14,27 @@ # with embedded macros that you may find superior to what is in here. # See Tools/gdb/libpython.py and http://bugs.python.org/issue8032. -document pyo - Prints a representation of the object to stderr, along with the - number of reference counts it currently has and the hex address the - object is allocated at. The argument must be a PyObject* -end define pyo # side effect of calling _PyObject_Dump is to dump the object's # info - assigning just prevents gdb from printing the # NULL return value set $_unused_void = _PyObject_Dump($arg0) end - -document pyg +document pyo Prints a representation of the object to stderr, along with the number of reference counts it currently has and the hex address the - object is allocated at. The argument must be a PyGC_Head* + object is allocated at. The argument must be a PyObject* end + define pyg print _PyGC_Dump($arg0) end - -document pylocals - Print the local variables of the current frame. +document pyg + Prints a representation of the object to stderr, along with the + number of reference counts it currently has and the hex address the + object is allocated at. The argument must be a PyGC_Head* end + define pylocals set $_i = 0 while $_i < f->f_code->co_nlocals @@ -50,6 +47,9 @@ define pylocals set $_i = $_i + 1 end end +document pylocals + Print the local variables of the current frame. +end # A rewrite of the Python interpreter's line number calculator in GDB's # command language @@ -75,13 +75,13 @@ define lineno printf "%d", $__li end -document pyframev - Print the current frame - verbose -end define pyframev pyframe pylocals end +document pyframev + Print the current frame - verbose +end define pyframe set $__fn = PyUnicode_AsUTF8(f->f_code->co_filename) @@ -134,9 +134,6 @@ end # the interpreter you may will have to change the functions you compare with # $pc. -document pystack - Print the entire Python call stack -end define pystack while $pc < Py_Main || $pc > Py_GetArgcArgv if $pc > PyEval_EvalFrameEx && $pc < _PyEval_EvalFrameDefault @@ -146,10 +143,10 @@ define pystack end select-frame 0 end - -document pystackv - Print the entire Python call stack - verbose mode +document pystack + Print the entire Python call stack end + define pystackv while $pc < Py_Main || $pc > Py_GetArgcArgv if $pc > PyEval_EvalFrameEx && $pc < _PyEval_EvalFrameDefault @@ -159,10 +156,10 @@ define pystackv end select-frame 0 end - -document pu - Generally useful macro to print a Unicode string +document pystackv + Print the entire Python call stack - verbose mode end + def pu set $uni = $arg0 set $i = 0 @@ -174,3 +171,6 @@ def pu end end end +document pu + Generally useful macro to print a Unicode string +end diff --git a/Misc/python-config.sh.in b/Misc/python-config.sh.in index 59101d5a5580b5..2602fe24c0402e 100644 --- a/Misc/python-config.sh.in +++ b/Misc/python-config.sh.in @@ -4,7 +4,7 @@ exit_with_usage () { - echo "Usage: $0 --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--help|--abiflags|--configdir" + echo "Usage: $0 --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--help|--abiflags|--configdir|--embed" exit $1 } diff --git a/Misc/python.man b/Misc/python.man index 8d5ad8cd6ca87f..3aa9f1f9c7eace 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -431,7 +431,7 @@ If this is set to a comma-separated string it is equivalent to specifying the \fB\-W\fP option for each separate value. .IP PYTHONHASHSEED If this variable is set to "random", a random value is used to seed the hashes -of str, bytes and datetime objects. +of str and bytes objects. If PYTHONHASHSEED is set to an integer value, it is used as a fixed seed for generating the hash() of the types covered by the hash randomization. Its diff --git a/Misc/valgrind-python.supp b/Misc/valgrind-python.supp index bc8f77f261a805..38a5ea3cd2b828 100644 --- a/Misc/valgrind-python.supp +++ b/Misc/valgrind-python.supp @@ -283,6 +283,17 @@ fun:rl_initialize } +# Valgrind emits "Conditional jump or move depends on uninitialised value(s)" +# false alarms on GCC builtin strcmp() function. The GCC code is correct. +# +# Valgrind bug: https://bugs.kde.org/show_bug.cgi?id=264936 +{ + bpo-38118: Valgrind emits false alarm on GCC builtin strcmp() + Memcheck:Cond + fun:PyUnicode_Decode +} + + ### ### These occur from somewhere within the SSL, when running ### test_socket_sll. They are too general to leave on by default. diff --git a/Modules/Setup b/Modules/Setup index e729ab883f410b..983fa014ecb242 100644 --- a/Modules/Setup +++ b/Modules/Setup @@ -182,6 +182,7 @@ _symtable symtablemodule.c #_heapq _heapqmodule.c # Heap queue algorithm #_asyncio _asynciomodule.c # Fast asyncio Future #_json -I$(srcdir)/Include/internal -DPy_BUILD_CORE_BUILTIN _json.c # _json speedups +#_statistics _statisticsmodule.c # statistics accelerator #unicodedata unicodedata.c # static Unicode character database @@ -338,7 +339,7 @@ _symtable symtablemodule.c # Interface to the Expat XML parser # More information on Expat can be found at www.libexpat.org. # -#pyexpat expat/xmlparse.c expat/xmlrole.c expat/xmltok.c pyexpat.c -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DXML_POOR_ENTROPY=1 -DUSE_PYEXPAT_CAPI +#pyexpat expat/xmlparse.c expat/xmlrole.c expat/xmltok.c pyexpat.c -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DXML_POOR_ENTROPY -DUSE_PYEXPAT_CAPI # Hye-Shik Chang's CJKCodecs diff --git a/Modules/_abc.c b/Modules/_abc.c index 1fbf3a831007bd..de938dd0d7d525 100644 --- a/Modules/_abc.c +++ b/Modules/_abc.c @@ -547,7 +547,7 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self, } -// Return -1 when exception occured. +// Return -1 when exception occurred. // Return 1 when result is set. // Return 0 otherwise. static int subclasscheck_check_registry(_abc_data *impl, PyObject *subclass, @@ -659,7 +659,7 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, /* 5. Check if it's a subclass of a registered class (recursive). */ if (subclasscheck_check_registry(impl, subclass, &result)) { - // Exception occured or result is set. + // Exception occurred or result is set. goto end; } diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 281161b68611ae..5261ed3d4c3d06 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -33,6 +33,7 @@ static PyObject *asyncio_task_repr_info_func; static PyObject *asyncio_InvalidStateError; static PyObject *asyncio_CancelledError; static PyObject *context_kwname; +static int module_initialized; static PyObject *cached_running_holder; static volatile uint64_t cached_running_holder_tsid; @@ -2635,18 +2636,19 @@ task_step_impl(TaskObj *task, PyObject *exc) if (_PyGen_FetchStopIterationValue(&o) == 0) { /* The error is StopIteration and that means that the underlying coroutine has resolved */ + + PyObject *res; if (task->task_must_cancel) { // Task is cancelled right before coro stops. - Py_DECREF(o); task->task_must_cancel = 0; - et = asyncio_CancelledError; - Py_INCREF(et); - ev = NULL; - tb = NULL; - goto set_exception; + res = future_cancel((FutureObj*)task); + } + else { + res = future_set_result((FutureObj*)task, o); } - PyObject *res = future_set_result((FutureObj*)task, o); + Py_DECREF(o); + if (res == NULL) { return NULL; } @@ -2663,7 +2665,6 @@ task_step_impl(TaskObj *task, PyObject *exc) /* Some other exception; pop it and call Task.set_exception() */ PyErr_Fetch(&et, &ev, &tb); -set_exception: assert(et); if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) { PyErr_NormalizeException(&et, &ev, &tb); @@ -3254,6 +3255,12 @@ module_init(void) if (asyncio_mod == NULL) { goto fail; } + if (module_initialized != 0) { + return 0; + } + else { + module_initialized = 1; + } current_tasks = PyDict_New(); if (current_tasks == NULL) { diff --git a/Modules/_blake2/clinic/blake2b_impl.c.h b/Modules/_blake2/clinic/blake2b_impl.c.h index 09fe00457f352d..cd329c07c99981 100644 --- a/Modules/_blake2/clinic/blake2b_impl.c.h +++ b/Modules/_blake2/clinic/blake2b_impl.c.h @@ -72,7 +72,7 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } if (!PyBuffer_IsContiguous(&key, 'C')) { - _PyArg_BadArgument("blake2b", 3, "contiguous buffer", fastargs[2]); + _PyArg_BadArgument("blake2b", "argument 'key'", "contiguous buffer", fastargs[2]); goto exit; } if (!--noptargs) { @@ -84,7 +84,7 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } if (!PyBuffer_IsContiguous(&salt, 'C')) { - _PyArg_BadArgument("blake2b", 4, "contiguous buffer", fastargs[3]); + _PyArg_BadArgument("blake2b", "argument 'salt'", "contiguous buffer", fastargs[3]); goto exit; } if (!--noptargs) { @@ -96,7 +96,7 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } if (!PyBuffer_IsContiguous(&person, 'C')) { - _PyArg_BadArgument("blake2b", 5, "contiguous buffer", fastargs[4]); + _PyArg_BadArgument("blake2b", "argument 'person'", "contiguous buffer", fastargs[4]); goto exit; } if (!--noptargs) { @@ -261,4 +261,4 @@ _blake2_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2b_hexdigest_impl(self); } -/*[clinic end generated code: output=a91d182ce1109f34 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=cbb625d7f60c288c input=a9049054013a1b77]*/ diff --git a/Modules/_blake2/clinic/blake2s_impl.c.h b/Modules/_blake2/clinic/blake2s_impl.c.h index 92739a1feb321e..560bd68160b016 100644 --- a/Modules/_blake2/clinic/blake2s_impl.c.h +++ b/Modules/_blake2/clinic/blake2s_impl.c.h @@ -72,7 +72,7 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } if (!PyBuffer_IsContiguous(&key, 'C')) { - _PyArg_BadArgument("blake2s", 3, "contiguous buffer", fastargs[2]); + _PyArg_BadArgument("blake2s", "argument 'key'", "contiguous buffer", fastargs[2]); goto exit; } if (!--noptargs) { @@ -84,7 +84,7 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } if (!PyBuffer_IsContiguous(&salt, 'C')) { - _PyArg_BadArgument("blake2s", 4, "contiguous buffer", fastargs[3]); + _PyArg_BadArgument("blake2s", "argument 'salt'", "contiguous buffer", fastargs[3]); goto exit; } if (!--noptargs) { @@ -96,7 +96,7 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } if (!PyBuffer_IsContiguous(&person, 'C')) { - _PyArg_BadArgument("blake2s", 5, "contiguous buffer", fastargs[4]); + _PyArg_BadArgument("blake2s", "argument 'person'", "contiguous buffer", fastargs[4]); goto exit; } if (!--noptargs) { @@ -261,4 +261,4 @@ _blake2_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2s_hexdigest_impl(self); } -/*[clinic end generated code: output=ae8e9b7301d092b4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=39af5a74c8805b36 input=a9049054013a1b77]*/ diff --git a/Modules/_blake2/impl/blake2.h b/Modules/_blake2/impl/blake2.h index 5ca17f610742c9..a08d82efefe09f 100644 --- a/Modules/_blake2/impl/blake2.h +++ b/Modules/_blake2/impl/blake2.h @@ -169,11 +169,6 @@ extern "C" { BLAKE2_API int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); BLAKE2_API int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - static inline int blake2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) - { - return blake2b( out, in, key, outlen, inlen, keylen ); - } - #if defined(__cplusplus) } #endif diff --git a/Modules/_blake2/impl/blake2b.c b/Modules/_blake2/impl/blake2b.c index ca150462235433..3d3e46506f2e7d 100644 --- a/Modules/_blake2/impl/blake2b.c +++ b/Modules/_blake2/impl/blake2b.c @@ -189,13 +189,6 @@ static inline int blake2b_init0( blake2b_state *S ) -#define blake2b_init BLAKE2_IMPL_NAME(blake2b_init) -#define blake2b_init_param BLAKE2_IMPL_NAME(blake2b_init_param) -#define blake2b_init_key BLAKE2_IMPL_NAME(blake2b_init_key) -#define blake2b_update BLAKE2_IMPL_NAME(blake2b_update) -#define blake2b_final BLAKE2_IMPL_NAME(blake2b_final) -#define blake2b BLAKE2_IMPL_NAME(blake2b) - #if defined(__cplusplus) extern "C" { #endif diff --git a/Modules/_blake2/impl/blake2s.c b/Modules/_blake2/impl/blake2s.c index 0c3636ef6fc5e8..3a04328ab8a4f1 100644 --- a/Modules/_blake2/impl/blake2s.c +++ b/Modules/_blake2/impl/blake2s.c @@ -175,13 +175,6 @@ static inline int blake2s_init0( blake2s_state *S ) return 0; } -#define blake2s_init BLAKE2_IMPL_NAME(blake2s_init) -#define blake2s_init_param BLAKE2_IMPL_NAME(blake2s_init_param) -#define blake2s_init_key BLAKE2_IMPL_NAME(blake2s_init_key) -#define blake2s_update BLAKE2_IMPL_NAME(blake2s_update) -#define blake2s_final BLAKE2_IMPL_NAME(blake2s_final) -#define blake2s BLAKE2_IMPL_NAME(blake2s) - #if defined(__cplusplus) extern "C" { #endif diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index 90b3e37d16414c..a8ffb699557abf 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -171,14 +171,14 @@ PyObject *codec_tuple(PyObject *decoded, /*[clinic input] _codecs.escape_decode data: Py_buffer(accept={str, buffer}) - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_escape_decode_impl(PyObject *module, Py_buffer *data, const char *errors) -/*[clinic end generated code: output=505200ba8056979a input=0018edfd99db714d]*/ +/*[clinic end generated code: output=505200ba8056979a input=77298a561c90bd82]*/ { PyObject *decoded = PyBytes_DecodeEscape(data->buf, data->len, errors, 0, NULL); @@ -188,14 +188,14 @@ _codecs_escape_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.escape_encode data: object(subclass_of='&PyBytes_Type') - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_escape_encode_impl(PyObject *module, PyObject *data, const char *errors) -/*[clinic end generated code: output=4af1d477834bab34 input=da9ded00992f32f2]*/ +/*[clinic end generated code: output=4af1d477834bab34 input=8f4b144799a94245]*/ { Py_ssize_t size; Py_ssize_t newsize; @@ -252,7 +252,7 @@ _codecs_escape_encode_impl(PyObject *module, PyObject *data, /*[clinic input] _codecs.utf_7_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = False / [clinic start generated code]*/ @@ -260,7 +260,7 @@ _codecs.utf_7_decode static PyObject * _codecs_utf_7_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=0cd3a944a32a4089 input=2d94a5a1f170c8ae]*/ +/*[clinic end generated code: output=0cd3a944a32a4089 input=22c395d357815d26]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeUTF7Stateful(data->buf, data->len, @@ -272,7 +272,7 @@ _codecs_utf_7_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.utf_8_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = False / [clinic start generated code]*/ @@ -280,7 +280,7 @@ _codecs.utf_8_decode static PyObject * _codecs_utf_8_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=10f74dec8d9bb8bf input=1ea6c21492e8bcbe]*/ +/*[clinic end generated code: output=10f74dec8d9bb8bf input=f611b3867352ba59]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeUTF8Stateful(data->buf, data->len, @@ -292,7 +292,7 @@ _codecs_utf_8_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.utf_16_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = False / [clinic start generated code]*/ @@ -300,7 +300,7 @@ _codecs.utf_16_decode static PyObject * _codecs_utf_16_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=783b442abcbcc2d0 input=2ba128c28ea0bb40]*/ +/*[clinic end generated code: output=783b442abcbcc2d0 input=191d360bd7309180]*/ { int byteorder = 0; /* This is overwritten unless final is true. */ @@ -314,7 +314,7 @@ _codecs_utf_16_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.utf_16_le_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = False / [clinic start generated code]*/ @@ -322,7 +322,7 @@ _codecs.utf_16_le_decode 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=43aeb8b0461cace5]*/ +/*[clinic end generated code: output=899b9e6364379dcd input=c6904fdc27fb4724]*/ { int byteorder = -1; /* This is overwritten unless final is true. */ @@ -336,7 +336,7 @@ _codecs_utf_16_le_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.utf_16_be_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = False / [clinic start generated code]*/ @@ -344,7 +344,7 @@ _codecs.utf_16_be_decode 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=339e554c804f34b2]*/ +/*[clinic end generated code: output=49f6465ea07669c8 input=e49012400974649b]*/ { int byteorder = 1; /* This is overwritten unless final is true. */ @@ -365,7 +365,7 @@ _codecs_utf_16_be_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.utf_16_ex_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None byteorder: int = 0 final: bool(accept={int}) = False / @@ -374,7 +374,7 @@ _codecs.utf_16_ex_decode 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=3201aeddb9636889]*/ +/*[clinic end generated code: output=0f385f251ecc1988 input=5a9c19f2e6b6cf0e]*/ { /* This is overwritten unless final is true. */ Py_ssize_t consumed = data->len; @@ -390,7 +390,7 @@ _codecs_utf_16_ex_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.utf_32_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = False / [clinic start generated code]*/ @@ -398,7 +398,7 @@ _codecs.utf_32_decode static PyObject * _codecs_utf_32_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=2fc961807f7b145f input=155a5c673a4e2514]*/ +/*[clinic end generated code: output=2fc961807f7b145f input=fd7193965627eb58]*/ { int byteorder = 0; /* This is overwritten unless final is true. */ @@ -412,7 +412,7 @@ _codecs_utf_32_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.utf_32_le_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = False / [clinic start generated code]*/ @@ -420,7 +420,7 @@ _codecs.utf_32_le_decode 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=7baf061069e92d3b]*/ +/*[clinic end generated code: output=ec8f46b67a94f3e6 input=9078ec70acfe7613]*/ { int byteorder = -1; /* This is overwritten unless final is true. */ @@ -434,7 +434,7 @@ _codecs_utf_32_le_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.utf_32_be_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = False / [clinic start generated code]*/ @@ -442,7 +442,7 @@ _codecs.utf_32_be_decode 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=b182026300dae595]*/ +/*[clinic end generated code: output=ff82bae862c92c4e input=f1ae1bbbb86648ff]*/ { int byteorder = 1; /* This is overwritten unless final is true. */ @@ -463,7 +463,7 @@ _codecs_utf_32_be_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.utf_32_ex_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None byteorder: int = 0 final: bool(accept={int}) = False / @@ -472,7 +472,7 @@ _codecs.utf_32_ex_decode 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=7b9c2cb819fb237a]*/ +/*[clinic end generated code: output=6bfb177dceaf4848 input=e46a73bc859d0bd0]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len, @@ -486,14 +486,14 @@ _codecs_utf_32_ex_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.unicode_escape_decode data: Py_buffer(accept={str, buffer}) - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, const char *errors) -/*[clinic end generated code: output=3ca3c917176b82ab input=49fd27d06813a7f5]*/ +/*[clinic end generated code: output=3ca3c917176b82ab input=8328081a3a569bd6]*/ { PyObject *decoded = PyUnicode_DecodeUnicodeEscape(data->buf, data->len, errors); @@ -503,14 +503,14 @@ _codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.raw_unicode_escape_decode data: Py_buffer(accept={str, buffer}) - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_raw_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, const char *errors) -/*[clinic end generated code: output=c98eeb56028070a6 input=770903a211434ebc]*/ +/*[clinic end generated code: output=c98eeb56028070a6 input=d2f5159ce3b3392f]*/ { PyObject *decoded = PyUnicode_DecodeRawUnicodeEscape(data->buf, data->len, errors); @@ -520,14 +520,14 @@ _codecs_raw_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.latin_1_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_latin_1_decode_impl(PyObject *module, Py_buffer *data, const char *errors) -/*[clinic end generated code: output=07f3dfa3f72c7d8f input=5cad0f1759c618ec]*/ +/*[clinic end generated code: output=07f3dfa3f72c7d8f input=76ca58fd6dcd08c7]*/ { PyObject *decoded = PyUnicode_DecodeLatin1(data->buf, data->len, errors); return codec_tuple(decoded, data->len); @@ -536,14 +536,14 @@ _codecs_latin_1_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.ascii_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_ascii_decode_impl(PyObject *module, Py_buffer *data, const char *errors) -/*[clinic end generated code: output=2627d72058d42429 input=ad1106f64037bd16]*/ +/*[clinic end generated code: output=2627d72058d42429 input=e428a267a04b4481]*/ { PyObject *decoded = PyUnicode_DecodeASCII(data->buf, data->len, errors); return codec_tuple(decoded, data->len); @@ -552,15 +552,15 @@ _codecs_ascii_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.charmap_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL - mapping: object = NULL + errors: str(accept={str, NoneType}) = None + mapping: object = None / [clinic start generated code]*/ static PyObject * _codecs_charmap_decode_impl(PyObject *module, Py_buffer *data, const char *errors, PyObject *mapping) -/*[clinic end generated code: output=2c335b09778cf895 input=19712ca35c5a80e2]*/ +/*[clinic end generated code: output=2c335b09778cf895 input=15b69df43458eb40]*/ { PyObject *decoded; @@ -576,7 +576,7 @@ _codecs_charmap_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.mbcs_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = False / [clinic start generated code]*/ @@ -584,7 +584,7 @@ _codecs.mbcs_decode static PyObject * _codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=39b65b8598938c4b input=b5f2fe568f311297]*/ +/*[clinic end generated code: output=39b65b8598938c4b input=1c1d50f08fa53789]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeMBCSStateful(data->buf, data->len, @@ -595,7 +595,7 @@ _codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.oem_decode data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = False / [clinic start generated code]*/ @@ -603,7 +603,7 @@ _codecs.oem_decode static PyObject * _codecs_oem_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=da1617612f3fcad8 input=278709bcfd374a9c]*/ +/*[clinic end generated code: output=da1617612f3fcad8 input=81b67cba811022e5]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeCodePageStateful(CP_OEMCP, @@ -615,7 +615,7 @@ _codecs_oem_decode_impl(PyObject *module, Py_buffer *data, _codecs.code_page_decode codepage: int data: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = False / [clinic start generated code]*/ @@ -623,7 +623,7 @@ _codecs.code_page_decode 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=51f6169021c68dd5]*/ +/*[clinic end generated code: output=53008ea967da3fff input=c5f58d036cb63575]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeCodePageStateful(codepage, @@ -640,14 +640,14 @@ _codecs_code_page_decode_impl(PyObject *module, int codepage, /*[clinic input] _codecs.readbuffer_encode data: Py_buffer(accept={str, buffer}) - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_readbuffer_encode_impl(PyObject *module, Py_buffer *data, const char *errors) -/*[clinic end generated code: output=c645ea7cdb3d6e86 input=b7c322b89d4ab923]*/ +/*[clinic end generated code: output=c645ea7cdb3d6e86 input=aa10cfdf252455c5]*/ { PyObject *result = PyBytes_FromStringAndSize(data->buf, data->len); return codec_tuple(result, data->len); @@ -656,14 +656,14 @@ _codecs_readbuffer_encode_impl(PyObject *module, Py_buffer *data, /*[clinic input] _codecs.utf_7_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_utf_7_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=0feda21ffc921bc8 input=d1a47579e79cbe15]*/ +/*[clinic end generated code: output=0feda21ffc921bc8 input=2546dbbb3fa53114]*/ { return codec_tuple(_PyUnicode_EncodeUTF7(str, 0, 0, errors), PyUnicode_GET_LENGTH(str)); @@ -672,14 +672,14 @@ _codecs_utf_7_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.utf_8_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_utf_8_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=02bf47332b9c796c input=42e3ba73c4392eef]*/ +/*[clinic end generated code: output=02bf47332b9c796c input=a3e71ae01c3f93f3]*/ { return codec_tuple(_PyUnicode_AsUTF8String(str, errors), PyUnicode_GET_LENGTH(str)); @@ -695,7 +695,7 @@ _codecs_utf_8_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.utf_16_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None byteorder: int = 0 / [clinic start generated code]*/ @@ -703,7 +703,7 @@ _codecs.utf_16_encode static PyObject * _codecs_utf_16_encode_impl(PyObject *module, PyObject *str, const char *errors, int byteorder) -/*[clinic end generated code: output=c654e13efa2e64e4 input=ff46416b04edb944]*/ +/*[clinic end generated code: output=c654e13efa2e64e4 input=68cdc2eb8338555d]*/ { return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, byteorder), PyUnicode_GET_LENGTH(str)); @@ -712,14 +712,14 @@ _codecs_utf_16_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.utf_16_le_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_utf_16_le_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=431b01e55f2d4995 input=cb385455ea8f2fe0]*/ +/*[clinic end generated code: output=431b01e55f2d4995 input=83d042706eed6798]*/ { return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, -1), PyUnicode_GET_LENGTH(str)); @@ -728,14 +728,14 @@ _codecs_utf_16_le_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.utf_16_be_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_utf_16_be_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=96886a6fd54dcae3 input=9119997066bdaefd]*/ +/*[clinic end generated code: output=96886a6fd54dcae3 input=6f1e9e623b03071b]*/ { return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, +1), PyUnicode_GET_LENGTH(str)); @@ -751,7 +751,7 @@ _codecs_utf_16_be_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.utf_32_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None byteorder: int = 0 / [clinic start generated code]*/ @@ -759,7 +759,7 @@ _codecs.utf_32_encode static PyObject * _codecs_utf_32_encode_impl(PyObject *module, PyObject *str, const char *errors, int byteorder) -/*[clinic end generated code: output=5c760da0c09a8b83 input=c5e77da82fbe5c2a]*/ +/*[clinic end generated code: output=5c760da0c09a8b83 input=8ec4c64d983bc52b]*/ { return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, byteorder), PyUnicode_GET_LENGTH(str)); @@ -768,14 +768,14 @@ _codecs_utf_32_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.utf_32_le_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_utf_32_le_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=b65cd176de8e36d6 input=9993b25fe0877848]*/ +/*[clinic end generated code: output=b65cd176de8e36d6 input=f0918d41de3eb1b1]*/ { return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, -1), PyUnicode_GET_LENGTH(str)); @@ -784,14 +784,14 @@ _codecs_utf_32_le_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.utf_32_be_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_utf_32_be_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=1d9e71a9358709e9 input=d3e0ccaa02920431]*/ +/*[clinic end generated code: output=1d9e71a9358709e9 input=967a99a95748b557]*/ { return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, +1), PyUnicode_GET_LENGTH(str)); @@ -800,14 +800,14 @@ _codecs_utf_32_be_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.unicode_escape_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_unicode_escape_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=66271b30bc4f7a3c input=65d9eefca65b455a]*/ +/*[clinic end generated code: output=66271b30bc4f7a3c input=8c4de07597054e33]*/ { return codec_tuple(PyUnicode_AsUnicodeEscapeString(str), PyUnicode_GET_LENGTH(str)); @@ -816,14 +816,14 @@ _codecs_unicode_escape_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.raw_unicode_escape_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_raw_unicode_escape_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=a66a806ed01c830a input=5aa33e4a133391ab]*/ +/*[clinic end generated code: output=a66a806ed01c830a input=4aa6f280d78e4574]*/ { return codec_tuple(PyUnicode_AsRawUnicodeEscapeString(str), PyUnicode_GET_LENGTH(str)); @@ -832,14 +832,14 @@ _codecs_raw_unicode_escape_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.latin_1_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_latin_1_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=2c28c83a27884e08 input=30b11c9e49a65150]*/ +/*[clinic end generated code: output=2c28c83a27884e08 input=ec3ef74bf85c5c5d]*/ { return codec_tuple(_PyUnicode_AsLatin1String(str, errors), PyUnicode_GET_LENGTH(str)); @@ -848,14 +848,14 @@ _codecs_latin_1_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.ascii_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_ascii_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=b5e035182d33befc input=843a1d268e6dfa8e]*/ +/*[clinic end generated code: output=b5e035182d33befc input=93e6e602838bd3de]*/ { return codec_tuple(_PyUnicode_AsASCIIString(str, errors), PyUnicode_GET_LENGTH(str)); @@ -864,15 +864,15 @@ _codecs_ascii_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.charmap_encode str: unicode - errors: str(accept={str, NoneType}) = NULL - mapping: object = NULL + errors: str(accept={str, NoneType}) = None + mapping: object = None / [clinic start generated code]*/ static PyObject * _codecs_charmap_encode_impl(PyObject *module, PyObject *str, const char *errors, PyObject *mapping) -/*[clinic end generated code: output=047476f48495a9e9 input=0752cde07a6d6d00]*/ +/*[clinic end generated code: output=047476f48495a9e9 input=2a98feae73dadce8]*/ { if (mapping == Py_None) mapping = NULL; @@ -899,13 +899,13 @@ _codecs_charmap_build_impl(PyObject *module, PyObject *map) /*[clinic input] _codecs.mbcs_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_mbcs_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=76e2e170c966c080 input=de471e0815947553]*/ +/*[clinic end generated code: output=76e2e170c966c080 input=2e932fc289ea5a5b]*/ { return codec_tuple(PyUnicode_EncodeCodePage(CP_ACP, str, errors), PyUnicode_GET_LENGTH(str)); @@ -914,13 +914,13 @@ _codecs_mbcs_encode_impl(PyObject *module, PyObject *str, const char *errors) /*[clinic input] _codecs.oem_encode str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_oem_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=65d5982c737de649 input=3fc5f0028aad3cda]*/ +/*[clinic end generated code: output=65d5982c737de649 input=9eac86dc21eb14f2]*/ { return codec_tuple(PyUnicode_EncodeCodePage(CP_OEMCP, str, errors), PyUnicode_GET_LENGTH(str)); @@ -930,14 +930,14 @@ _codecs_oem_encode_impl(PyObject *module, PyObject *str, const char *errors) _codecs.code_page_encode code_page: int str: unicode - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None / [clinic start generated code]*/ static PyObject * _codecs_code_page_encode_impl(PyObject *module, int code_page, PyObject *str, const char *errors) -/*[clinic end generated code: output=45673f6085657a9e input=786421ae617d680b]*/ +/*[clinic end generated code: output=45673f6085657a9e input=7d18a33bc8cd0f94]*/ { return codec_tuple(PyUnicode_EncodeCodePage(code_page, str, errors), PyUnicode_GET_LENGTH(str)); diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index dacea3a0243914..45169ecd11af00 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -8,9 +8,10 @@ #endif /*[clinic input] +module _collections class _tuplegetter "_tuplegetterobject *" "&tuplegetter_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ee5ed5baabe35068]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a8ece4ccad7e30ac]*/ static PyTypeObject tuplegetter_type; #include "clinic/_collectionsmodule.c.h" @@ -2228,17 +2229,24 @@ static PyTypeObject defdict_type = { /* helper function for Counter *********************************************/ -PyDoc_STRVAR(_count_elements_doc, -"_count_elements(mapping, iterable) -> None\n\ -\n\ -Count elements in the iterable, updating the mapping"); +/*[clinic input] +_collections._count_elements + + mapping: object + iterable: object + / + +Count elements in the iterable, updating the mapping +[clinic start generated code]*/ static PyObject * -_count_elements(PyObject *self, PyObject *args) +_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, *iterable, *mapping, *oldval; + PyObject *it, *oldval; PyObject *newval = NULL; PyObject *key = NULL; PyObject *bound_get = NULL; @@ -2247,9 +2255,6 @@ _count_elements(PyObject *self, PyObject *args) PyObject *mapping_setitem; PyObject *dict_setitem; - if (!PyArg_UnpackTuple(args, "_count_elements", 2, 2, &mapping, &iterable)) - return NULL; - it = PyObject_GetIter(iterable); if (it == NULL) return NULL; @@ -2510,7 +2515,7 @@ PyDoc_STRVAR(module_doc, "); static struct PyMethodDef module_functions[] = { - {"_count_elements", _count_elements, METH_VARARGS, _count_elements_doc}, + _COLLECTIONS__COUNT_ELEMENTS_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_csv.c b/Modules/_csv.c index 7eb9d8b796dd78..46d414383cbd20 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -826,7 +826,7 @@ Reader_iternext(ReaderObj *self) if (c == '\0') { Py_DECREF(lineobj); PyErr_Format(_csvstate_global->error_obj, - "line contains NULL byte"); + "line contains NUL"); goto err; } if (parse_process_char(self, c) < 0) { @@ -1382,7 +1382,10 @@ csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args) Py_DECREF(self); return NULL; } - self->write = _PyObject_GetAttrId(output_file, &PyId_write); + if (_PyObject_LookupAttrId(output_file, &PyId_write, &self->write) < 0) { + Py_DECREF(self); + return NULL; + } if (self->write == NULL || !PyCallable_Check(self->write)) { PyErr_SetString(PyExc_TypeError, "argument 1 must have a \"write\" method"); diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index f7513a3d74c4bc..0f11e01e111056 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -392,6 +392,35 @@ _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape, return result; } +/* StructParamObject and StructParam_Type are used in _ctypes_callproc() + for argument.keep to call PyMem_Free(ptr) on Py_DECREF(argument). + + StructUnionType_paramfunc() creates such object when a ctypes Structure is + passed by copy to a C function. */ +typedef struct { + PyObject_HEAD + void *ptr; +} StructParamObject; + + +static void +StructParam_dealloc(PyObject *myself) +{ + StructParamObject *self = (StructParamObject *)myself; + PyMem_Free(self->ptr); + Py_TYPE(self)->tp_free(myself); +} + + +static PyTypeObject StructParam_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_ctypes.StructParam_Type", + .tp_basicsize = sizeof(StructParamObject), + .tp_dealloc = StructParam_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + + /* PyCStructType_Type - a meta type/class. Creating a new class using this one as __metaclass__ will call the constructor StructUnionType_new. It replaces the @@ -403,35 +432,47 @@ static PyCArgObject * StructUnionType_paramfunc(CDataObject *self) { PyCArgObject *parg; - CDataObject *copied_self; + PyObject *obj; StgDictObject *stgdict; + void *ptr; if ((size_t)self->b_size > sizeof(void*)) { - void *new_ptr = PyMem_Malloc(self->b_size); - if (new_ptr == NULL) + ptr = PyMem_Malloc(self->b_size); + if (ptr == NULL) { + return NULL; + } + memcpy(ptr, self->b_ptr, self->b_size); + + /* Create a Python object which calls PyMem_Free(ptr) in + its deallocator. The object will be destroyed + at _ctypes_callproc() cleanup. */ + obj = (&StructParam_Type)->tp_alloc(&StructParam_Type, 0); + if (obj == NULL) { + PyMem_Free(ptr); return NULL; - memcpy(new_ptr, self->b_ptr, self->b_size); - copied_self = (CDataObject *)PyCData_AtAddress( - (PyObject *)Py_TYPE(self), new_ptr); - copied_self->b_needsfree = 1; + } + + StructParamObject *struct_param = (StructParamObject *)obj; + struct_param->ptr = ptr; } else { - copied_self = self; - Py_INCREF(copied_self); + ptr = self->b_ptr; + obj = (PyObject *)self; + Py_INCREF(obj); } parg = PyCArgObject_new(); if (parg == NULL) { - Py_DECREF(copied_self); + Py_DECREF(obj); return NULL; } parg->tag = 'V'; - stgdict = PyObject_stgdict((PyObject *)copied_self); + stgdict = PyObject_stgdict((PyObject *)self); assert(stgdict); /* Cannot be NULL for structure/union instances */ parg->pffi_type = &stgdict->ffi_type_pointer; - parg->value.p = copied_self->b_ptr; - parg->size = copied_self->b_size; - parg->obj = (PyObject *)copied_self; + parg->value.p = ptr; + parg->size = self->b_size; + parg->obj = obj; return parg; } @@ -1127,7 +1168,11 @@ PyCPointerType_from_param(PyObject *type, PyObject *value) */ StgDictObject *v = PyObject_stgdict(value); assert(v); /* Cannot be NULL for pointer or array objects */ - if (PyObject_IsSubclass(v->proto, typedict->proto)) { + int ret = PyObject_IsSubclass(v->proto, typedict->proto); + if (ret < 0) { + return NULL; + } + if (ret) { Py_INCREF(value); return value; } @@ -1518,7 +1563,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } itemsize = itemdict->size; - if (length > PY_SSIZE_T_MAX / itemsize) { + if (itemsize != 0 && length > PY_SSIZE_T_MAX / itemsize) { PyErr_SetString(PyExc_OverflowError, "array too large"); goto error; @@ -5700,6 +5745,10 @@ PyInit__ctypes(void) if (PyType_Ready(&DictRemover_Type) < 0) return NULL; + if (PyType_Ready(&StructParam_Type) < 0) { + return NULL; + } + #ifdef MS_WIN32 if (create_comerror() < 0) return NULL; diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index bae4976a08d31b..19066b31c1c875 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -74,6 +74,66 @@ _testfunc_reg_struct_update_value(TestReg in) ((volatile TestReg *)&in)->second = 0x0badf00d; } +/* + * See bpo-22273. Structs containing arrays should work on Linux 64-bit. + */ + +typedef struct { + unsigned char data[16]; +} Test2; + +EXPORT(int) +_testfunc_array_in_struct1(Test2 in) +{ + int result = 0; + + for (unsigned i = 0; i < 16; i++) + result += in.data[i]; + /* As the structure is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(in.data, 0, sizeof(in.data)); + return result; +} + +typedef struct { + double data[2]; +} Test3; + +typedef struct { + float data[2]; + float more_data[2]; +} Test3B; + +EXPORT(double) +_testfunc_array_in_struct2(Test3 in) +{ + double result = 0; + + for (unsigned i = 0; i < 2; i++) + result += in.data[i]; + /* As the structure is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(in.data, 0, sizeof(in.data)); + return result; +} + +EXPORT(double) +_testfunc_array_in_struct2a(Test3B in) +{ + double result = 0; + + for (unsigned i = 0; i < 2; i++) + result += in.data[i]; + for (unsigned i = 0; i < 2; i++) + result += in.more_data[i]; + /* As the structure is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(in.data, 0, sizeof(in.data)); + return result; +} EXPORT(void)testfunc_array(int values[4]) { diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 97463b599bc004..d2d9a6587d7995 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -422,8 +422,8 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, static void LoadPython(void) { if (!Py_IsInitialized()) { - PyEval_InitThreads(); Py_Initialize(); + PyEval_InitThreads(); } } diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 67665246414e21..d9bdd9881333d9 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -110,7 +110,7 @@ static void pymem_destructor(PyObject *ptr) WinDLL(..., use_last_error=True) swap the system LastError value with the ctypes private copy. - The values are also swapped immeditately before and after ctypes callback + The values are also swapped immediately before and after ctypes callback functions are called, if the callbacks are constructed using the new optional use_errno parameter set to True: CFUNCTYPE(..., use_errno=TRUE) or WINFUNCTYPE(..., use_errno=True). @@ -242,7 +242,9 @@ static WCHAR *FormatError(DWORD code) { WCHAR *lpMsgBuf; DWORD n; - n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 235a4d79ad2ca1..97bcf5539aeeab 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -350,9 +350,10 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct int pack; Py_ssize_t ffi_ofs; 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 sematics: _fields_ are not extended + be a way to use the old, broken semantics: _fields_ are not extended but replaced in subclasses. XXX Remove this in ctypes 1.0! @@ -501,6 +502,8 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct Py_XDECREF(pair); return -1; } + if (PyCArrayTypeObject_Check(desc)) + arrays_seen = 1; dict = PyType_stgdict(desc); if (dict == NULL) { Py_DECREF(pair); @@ -641,6 +644,240 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct stgdict->align = total_align; stgdict->length = len; /* ADD ffi_ofs? */ +#define MAX_STRUCT_SIZE 16 + + if (arrays_seen && (size <= MAX_STRUCT_SIZE)) { + /* + * See bpo-22273. Arrays are normally treated as pointers, which is + * fine when an array name is being passed as parameter, but not when + * passing structures by value that contain arrays. On 64-bit Linux, + * small structures passed by value are passed in registers, and in + * order to do this, libffi needs to know the true type of the array + * members of structs. Treating them as pointers breaks things. + * + * By small structures, we mean ones that are 16 bytes or less. In that + * case, there can't be more than 16 elements after unrolling arrays, + * as we (will) disallow bitfields. So we can collect the true ffi_type + * values in a fixed-size local array on the stack and, if any arrays + * were seen, replace the ffi_type_pointer.elements with a more + * accurate set, to allow libffi to marshal them into registers + * correctly. It means one more loop over the fields, but if we got + * here, the structure is small, so there aren't too many of those. + * + * Although the passing in registers is specific to 64-bit Linux, the + * array-in-struct vs. pointer problem is general. But we restrict the + * type transformation to small structs nonetheless. + * + * Note that although a union may be small in terms of memory usage, it + * could contain many overlapping declarations of arrays, e.g. + * + * union { + * unsigned int_8 foo [16]; + * unsigned uint_8 bar [16]; + * unsigned int_16 baz[8]; + * unsigned uint_16 bozz[8]; + * unsigned int_32 fizz[4]; + * unsigned uint_32 buzz[4]; + * } + * + * which is still only 16 bytes in size. We need to convert this into + * the following equivalent for libffi: + * + * union { + * struct { int_8 e1; int_8 e2; ... int_8 e_16; } f1; + * struct { uint_8 e1; uint_8 e2; ... uint_8 e_16; } f2; + * struct { int_16 e1; int_16 e2; ... int_16 e_8; } f3; + * struct { uint_16 e1; uint_16 e2; ... uint_16 e_8; } f4; + * struct { int_32 e1; int_32 e2; ... int_32 e_4; } f5; + * struct { uint_32 e1; uint_32 e2; ... uint_32 e_4; } f6; + * } + * + * So the struct/union needs setting up as follows: all non-array + * elements copied across as is, and all array elements replaced with + * an equivalent struct which has as many fields as the array has + * elements, plus one NULL pointer. + */ + + Py_ssize_t num_ffi_type_pointers = 0; /* for the dummy fields */ + Py_ssize_t num_ffi_types = 0; /* for the dummy structures */ + size_t alloc_size; /* total bytes to allocate */ + void *type_block; /* to hold all the type information needed */ + ffi_type **element_types; /* of this struct/union */ + ffi_type **dummy_types; /* of the dummy struct elements */ + ffi_type *structs; /* point to struct aliases of arrays */ + Py_ssize_t element_index; /* index into element_types for this */ + Py_ssize_t dummy_index = 0; /* index into dummy field pointers */ + Py_ssize_t struct_index = 0; /* index into dummy structs */ + + /* first pass to see how much memory to allocate */ + for (i = 0; i < len; ++i) { + PyObject *name, *desc; + PyObject *pair = PySequence_GetItem(fields, i); + StgDictObject *dict; + int bitsize = 0; + + if (pair == NULL) { + return -1; + } + if (!PyArg_ParseTuple(pair, "UO|i", &name, &desc, &bitsize)) { + PyErr_SetString(PyExc_TypeError, + "'_fields_' must be a sequence of (name, C type) pairs"); + Py_DECREF(pair); + return -1; + } + dict = PyType_stgdict(desc); + if (dict == NULL) { + Py_DECREF(pair); + PyErr_Format(PyExc_TypeError, + "second item in _fields_ tuple (index %zd) must be a C type", + i); + return -1; + } + if (!PyCArrayTypeObject_Check(desc)) { + /* Not an array. Just need an ffi_type pointer. */ + num_ffi_type_pointers++; + } + else { + /* It's an array. */ + Py_ssize_t length = dict->length; + StgDictObject *edict; + + edict = PyType_stgdict(dict->proto); + if (edict == NULL) { + Py_DECREF(pair); + PyErr_Format(PyExc_TypeError, + "second item in _fields_ tuple (index %zd) must be a C type", + i); + return -1; + } + /* + * We need one extra ffi_type to hold the struct, and one + * ffi_type pointer per array element + one for a NULL to + * mark the end. + */ + num_ffi_types++; + num_ffi_type_pointers += length + 1; + } + Py_DECREF(pair); + } + + /* + * At this point, we know we need storage for some ffi_types and some + * ffi_type pointers. We'll allocate these in one block. + * There are three sub-blocks of information: the ffi_type pointers to + * this structure/union's elements, the ffi_type_pointers to the + * dummy fields standing in for array elements, and the + * ffi_types representing the dummy structures. + */ + alloc_size = (ffi_ofs + 1 + len + num_ffi_type_pointers) * sizeof(ffi_type *) + + num_ffi_types * sizeof(ffi_type); + type_block = PyMem_Malloc(alloc_size); + + if (type_block == NULL) { + PyErr_NoMemory(); + return -1; + } + /* + * the first block takes up ffi_ofs + len + 1 which is the pointers * + * for this struct/union. The second block takes up + * num_ffi_type_pointers, so the sum of these is ffi_ofs + len + 1 + + * num_ffi_type_pointers as allocated above. The last bit is the + * num_ffi_types structs. + */ + element_types = (ffi_type **) type_block; + dummy_types = &element_types[ffi_ofs + len + 1]; + structs = (ffi_type *) &dummy_types[num_ffi_type_pointers]; + + if (num_ffi_types > 0) { + memset(structs, 0, num_ffi_types * sizeof(ffi_type)); + } + if (ffi_ofs && (basedict != NULL)) { + memcpy(element_types, + basedict->ffi_type_pointer.elements, + ffi_ofs * sizeof(ffi_type *)); + } + element_index = ffi_ofs; + + /* second pass to actually set the type pointers */ + for (i = 0; i < len; ++i) { + PyObject *name, *desc; + PyObject *pair = PySequence_GetItem(fields, i); + StgDictObject *dict; + int bitsize = 0; + + if (pair == NULL) { + PyMem_Free(type_block); + return -1; + } + /* In theory, we made this call in the first pass, so it *shouldn't* + * fail. However, you never know, and the code above might change + * later - keeping the check in here is a tad defensive but it + * will affect program size only slightly and performance hardly at + * all. + */ + if (!PyArg_ParseTuple(pair, "UO|i", &name, &desc, &bitsize)) { + PyErr_SetString(PyExc_TypeError, + "'_fields_' must be a sequence of (name, C type) pairs"); + Py_DECREF(pair); + PyMem_Free(type_block); + return -1; + } + dict = PyType_stgdict(desc); + /* Possibly this check could be avoided, but see above comment. */ + if (dict == NULL) { + Py_DECREF(pair); + PyMem_Free(type_block); + PyErr_Format(PyExc_TypeError, + "second item in _fields_ tuple (index %zd) must be a C type", + i); + return -1; + } + assert(element_index < (ffi_ofs + len)); /* will be used below */ + if (!PyCArrayTypeObject_Check(desc)) { + /* Not an array. Just copy over the element ffi_type. */ + element_types[element_index++] = &dict->ffi_type_pointer; + } + else { + Py_ssize_t length = dict->length; + StgDictObject *edict; + + edict = PyType_stgdict(dict->proto); + if (edict == NULL) { + Py_DECREF(pair); + PyMem_Free(type_block); + PyErr_Format(PyExc_TypeError, + "second item in _fields_ tuple (index %zd) must be a C type", + i); + return -1; + } + element_types[element_index++] = &structs[struct_index]; + structs[struct_index].size = length * edict->ffi_type_pointer.size; + structs[struct_index].alignment = edict->ffi_type_pointer.alignment; + structs[struct_index].type = FFI_TYPE_STRUCT; + structs[struct_index].elements = &dummy_types[dummy_index]; + ++struct_index; + /* Copy over the element's type, length times. */ + while (length > 0) { + assert(dummy_index < (num_ffi_type_pointers)); + dummy_types[dummy_index++] = &edict->ffi_type_pointer; + length--; + } + assert(dummy_index < (num_ffi_type_pointers)); + dummy_types[dummy_index++] = NULL; + } + Py_DECREF(pair); + } + + element_types[element_index] = NULL; + /* + * Replace the old elements with the new, taking into account + * base class elements where necessary. + */ + assert(stgdict->ffi_type_pointer.elements); + PyMem_Free(stgdict->ffi_type_pointer.elements); + stgdict->ffi_type_pointer.elements = element_types; + } + /* We did check that this flag was NOT set above, it must not have been set until now. */ if (stgdict->flags & DICTFLAG_FINAL) { diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 2435e1c1295514..b2b1117fb0934e 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -176,6 +176,18 @@ static char *screen_encoding = NULL; /* Utility Functions */ +static inline int +color_pair_to_attr(short color_number) +{ + return ((int)color_number << 8); +} + +static inline short +attr_to_color_pair(int attr) +{ + return (short)((attr & A_COLOR) >> 8); +} + /* * Check the return code from a curses function and return None * or raise an exception as appropriate. These are exported using the @@ -606,7 +618,7 @@ _curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, if (type == 2) { funcname = "add_wch"; wstr[1] = L'\0'; - setcchar(&wcval, wstr, attr, 0, NULL); + setcchar(&wcval, wstr, attr, attr_to_color_pair(attr), NULL); if (coordinates_group) rtn = mvwadd_wch(self->win,y,x, &wcval); else { @@ -2621,7 +2633,7 @@ _curses_color_pair_impl(PyObject *module, short color_number) PyCursesInitialised; PyCursesInitialisedColor; - return PyLong_FromLong((long) (color_number << 8)); + return PyLong_FromLong(color_pair_to_attr(color_number)); } /*[clinic input] @@ -3190,7 +3202,7 @@ _curses_initscr_impl(PyObject *module) /*[clinic input] _curses.setupterm - term: str(accept={str, NoneType}) = NULL + term: str(accept={str, NoneType}) = None Terminal name. If omitted, the value of the TERM environment variable will be used. fd: int = -1 @@ -3202,7 +3214,7 @@ Initialize the terminal. static PyObject * _curses_setupterm_impl(PyObject *module, const char *term, int fd) -/*[clinic end generated code: output=4584e587350f2848 input=8ac5f78ec6268be3]*/ +/*[clinic end generated code: output=4584e587350f2848 input=4511472766af0c12]*/ { int err; @@ -3644,7 +3656,7 @@ _curses_pair_number_impl(PyObject *module, int attr) PyCursesInitialised; PyCursesInitialisedColor; - return PyLong_FromLong((long) ((attr & A_COLOR) >> 8)); + return PyLong_FromLong(attr_to_color_pair(attr)); } /*[clinic input] @@ -4176,7 +4188,7 @@ PyCurses_ConvertToWchar_t(PyObject *obj, wchar_t buffer[2]; if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) { PyErr_Format(PyExc_TypeError, - "expect bytes or str of length 1, or int, " + "expect str of length 1 or int, " "got a str of length %zi", PyUnicode_GET_LENGTH(obj)); return 0; @@ -4203,7 +4215,7 @@ PyCurses_ConvertToWchar_t(PyObject *obj, } else { PyErr_Format(PyExc_TypeError, - "expect bytes or str of length 1, or int, got %s", + "expect str of length 1 or int, got %s", Py_TYPE(obj)->tp_name); return 0; } diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 4d3562cbe64f69..41c3f34269ddc6 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -32,6 +32,7 @@ #define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType) #define PyTZInfo_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TZInfoType) +#define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType) /*[clinic input] module datetime @@ -1099,7 +1100,9 @@ new_timezone(PyObject *offset, PyObject *name) Py_INCREF(PyDateTime_TimeZone_UTC); return PyDateTime_TimeZone_UTC; } - if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) || + if ((GET_TD_DAYS(offset) == -1 && + GET_TD_SECONDS(offset) == 0 && + GET_TD_MICROSECONDS(offset) < 1) || GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) { PyErr_Format(PyExc_ValueError, "offset must be a timedelta" " strictly between -timedelta(hours=24) and" @@ -1169,7 +1172,9 @@ call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg) if (offset == Py_None || offset == NULL) return offset; if (PyDelta_Check(offset)) { - if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) || + if ((GET_TD_DAYS(offset) == -1 && + GET_TD_SECONDS(offset) == 0 && + GET_TD_MICROSECONDS(offset) < 1) || GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) { Py_DECREF(offset); PyErr_Format(PyExc_ValueError, "offset must be a timedelta" @@ -3605,24 +3610,24 @@ tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) _Py_IDENTIFIER(__getinitargs__); _Py_IDENTIFIER(__getstate__); - getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__); + if (_PyObject_LookupAttrId(self, &PyId___getinitargs__, &getinitargs) < 0) { + return NULL; + } if (getinitargs != NULL) { args = _PyObject_CallNoArg(getinitargs); Py_DECREF(getinitargs); - if (args == NULL) { - return NULL; - } } else { - PyErr_Clear(); - args = PyTuple_New(0); - if (args == NULL) { - return NULL; - } + } + if (args == NULL) { + return NULL; } - getstate = _PyObject_GetAttrId(self, &PyId___getstate__); + if (_PyObject_LookupAttrId(self, &PyId___getstate__, &getstate) < 0) { + Py_DECREF(args); + return NULL; + } if (getstate != NULL) { state = _PyObject_CallNoArg(getstate); Py_DECREF(getstate); @@ -3633,7 +3638,6 @@ tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) } else { PyObject **dictptr; - PyErr_Clear(); state = Py_None; dictptr = _PyObject_GetDictPtr(self); if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) { @@ -3744,11 +3748,8 @@ timezone_richcompare(PyDateTime_TimeZone *self, { if (op != Py_EQ && op != Py_NE) Py_RETURN_NOTIMPLEMENTED; - if (Py_TYPE(other) != &PyDateTime_TimeZoneType) { - if (op == Py_EQ) - Py_RETURN_FALSE; - else - Py_RETURN_TRUE; + if (!PyTimezone_Check(other)) { + Py_RETURN_NOTIMPLEMENTED; } return delta_richcompare(self->offset, other->offset, op); } @@ -4079,7 +4080,7 @@ time_new(PyTypeObject *type, PyObject *args, PyObject *kw) return NULL; } if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE && - (0x7F & PyUnicode_READ_CHAR(state, 2)) < 24) + (0x7F & PyUnicode_READ_CHAR(state, 0)) < 24) { state = PyUnicode_AsLatin1String(state); if (state == NULL) { @@ -6487,6 +6488,9 @@ PyInit__datetime(void) PyDateTime_TimeZone_UTC = x; CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC; + /* bpo-37642: These attributes are rounded to the nearest minute for backwards + * compatibility, even though the constructor will accept a wider range of + * values. This may change in the future.*/ delta = new_delta(-1, 60, 0, 1); /* -23:59 */ if (delta == NULL) return NULL; diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 8119c8b1e2b10f..c3f30c9339cd0a 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2399,6 +2399,7 @@ typedef struct { PyObject *this; /* current node */ PyObject *last; /* most recently created node */ + PyObject *last_for_tail; /* most recently created node that takes a tail */ PyObject *data; /* data collector (string or list), or NULL */ @@ -2464,10 +2465,10 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) /*[clinic input] _elementtree.TreeBuilder.__init__ - element_factory: object = NULL + element_factory: object = None * - comment_factory: object = NULL - pi_factory: object = NULL + comment_factory: object = None + pi_factory: object = None insert_comments: bool = False insert_pis: bool = False @@ -2479,16 +2480,16 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, PyObject *comment_factory, PyObject *pi_factory, int insert_comments, int insert_pis) -/*[clinic end generated code: output=8571d4dcadfdf952 input=1f967b5c245e0a71]*/ +/*[clinic end generated code: output=8571d4dcadfdf952 input=ae98a94df20b5cc3]*/ { - if (element_factory && element_factory != Py_None) { + if (element_factory != Py_None) { Py_INCREF(element_factory); Py_XSETREF(self->element_factory, element_factory); } else { Py_CLEAR(self->element_factory); } - if (!comment_factory || comment_factory == Py_None) { + if (comment_factory == Py_None) { elementtreestate *st = ET_STATE_GLOBAL; comment_factory = st->comment_factory; } @@ -2501,7 +2502,7 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, self->insert_comments = 0; } - if (!pi_factory || pi_factory == Py_None) { + if (pi_factory == Py_None) { elementtreestate *st = ET_STATE_GLOBAL; pi_factory = st->pi_factory; } @@ -2530,6 +2531,7 @@ treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg) Py_VISIT(self->root); Py_VISIT(self->this); Py_VISIT(self->last); + Py_VISIT(self->last_for_tail); Py_VISIT(self->data); Py_VISIT(self->stack); Py_VISIT(self->pi_factory); @@ -2551,6 +2553,7 @@ treebuilder_gc_clear(TreeBuilderObject *self) Py_CLEAR(self->stack); Py_CLEAR(self->data); Py_CLEAR(self->last); + Py_CLEAR(self->last_for_tail); Py_CLEAR(self->this); Py_CLEAR(self->pi_factory); Py_CLEAR(self->comment_factory); @@ -2622,21 +2625,50 @@ _elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory, } static int -treebuilder_set_element_text_or_tail(PyObject *element, PyObject **data, - PyObject **dest, _Py_Identifier *name) +treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data, + PyObject **dest, _Py_Identifier *name) { + /* Fast paths for the "almost always" cases. */ if (Element_CheckExact(element)) { - PyObject *tmp = JOIN_OBJ(*dest); - *dest = JOIN_SET(*data, PyList_CheckExact(*data)); - *data = NULL; - Py_DECREF(tmp); - return 0; + PyObject *dest_obj = JOIN_OBJ(*dest); + if (dest_obj == Py_None) { + *dest = JOIN_SET(*data, PyList_CheckExact(*data)); + *data = NULL; + Py_DECREF(dest_obj); + return 0; + } + else if (JOIN_GET(*dest)) { + if (PyList_SetSlice(dest_obj, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, *data) < 0) { + return -1; + } + Py_CLEAR(*data); + return 0; + } } - else { - PyObject *joined = list_join(*data); + + /* Fallback for the non-Element / non-trivial cases. */ + { int r; - if (joined == NULL) + PyObject* joined; + PyObject* previous = _PyObject_GetAttrId(element, name); + if (!previous) return -1; + joined = list_join(*data); + if (!joined) { + Py_DECREF(previous); + return -1; + } + if (previous != Py_None) { + PyObject *tmp = PyNumber_Add(previous, joined); + Py_DECREF(joined); + Py_DECREF(previous); + if (!tmp) + return -1; + joined = tmp; + } else { + Py_DECREF(previous); + } + r = _PyObject_SetAttrId(element, name, joined); Py_DECREF(joined); if (r < 0) @@ -2649,21 +2681,21 @@ treebuilder_set_element_text_or_tail(PyObject *element, PyObject **data, LOCAL(int) treebuilder_flush_data(TreeBuilderObject* self) { - PyObject *element = self->last; - if (!self->data) { return 0; } - if (self->this == element) { + if (!self->last_for_tail) { + PyObject *element = self->last; _Py_IDENTIFIER(text); - return treebuilder_set_element_text_or_tail( + return treebuilder_extend_element_text_or_tail( element, &self->data, &((ElementObject *) element)->text, &PyId_text); } else { + PyObject *element = self->last_for_tail; _Py_IDENTIFIER(tail); - return treebuilder_set_element_text_or_tail( + return treebuilder_extend_element_text_or_tail( element, &self->data, &((ElementObject *) element)->tail, &PyId_tail); } @@ -2739,6 +2771,7 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, } this = self->this; + Py_CLEAR(self->last_for_tail); if (this != Py_None) { if (treebuilder_add_subelement(this, node) < 0) @@ -2836,6 +2869,8 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag) item = self->last; self->last = self->this; + Py_INCREF(self->last); + Py_XSETREF(self->last_for_tail, self->last); self->index--; self->this = PyList_GET_ITEM(self->stack, self->index); Py_INCREF(self->this); @@ -2851,7 +2886,7 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag) LOCAL(PyObject*) treebuilder_handle_comment(TreeBuilderObject* self, PyObject* text) { - PyObject* comment = NULL; + PyObject* comment; PyObject* this; if (treebuilder_flush_data(self) < 0) { @@ -2867,6 +2902,8 @@ treebuilder_handle_comment(TreeBuilderObject* self, PyObject* text) if (self->insert_comments && this != Py_None) { if (treebuilder_add_subelement(this, comment) < 0) goto error; + Py_INCREF(comment); + Py_XSETREF(self->last_for_tail, comment); } } else { Py_INCREF(text); @@ -2888,7 +2925,7 @@ treebuilder_handle_comment(TreeBuilderObject* self, PyObject* text) LOCAL(PyObject*) treebuilder_handle_pi(TreeBuilderObject* self, PyObject* target, PyObject* text) { - PyObject* pi = NULL; + PyObject* pi; PyObject* this; PyObject* stack[2] = {target, text}; @@ -2906,6 +2943,8 @@ treebuilder_handle_pi(TreeBuilderObject* self, PyObject* target, PyObject* text) if (self->insert_pis && this != Py_None) { if (treebuilder_add_subelement(this, pi) < 0) goto error; + Py_INCREF(pi); + Py_XSETREF(self->last_for_tail, pi); } } else { pi = PyTuple_Pack(2, target, text); @@ -3495,8 +3534,8 @@ expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) static void expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) { - PyObject* comment = NULL; - PyObject* res = NULL; + PyObject* comment; + PyObject* res; if (PyErr_Occurred()) return; @@ -3510,16 +3549,17 @@ expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) return; /* parser will look for errors */ res = treebuilder_handle_comment(target, comment); + Py_XDECREF(res); + Py_DECREF(comment); } else if (self->handle_comment) { comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict"); if (!comment) return; res = _PyObject_FastCall(self->handle_comment, &comment, 1); + Py_XDECREF(res); + Py_DECREF(comment); } - - Py_XDECREF(res); - Py_DECREF(comment); } static void @@ -3587,7 +3627,7 @@ static void expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, const XML_Char* data_in) { - PyObject* pi_target = NULL; + PyObject* pi_target; PyObject* data; PyObject* res; PyObject* stack[2]; @@ -3599,7 +3639,7 @@ expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, /* shortcut */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; - if (target->events_append && target->pi_event_obj) { + if ((target->events_append && target->pi_event_obj) || target->insert_pis) { pi_target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict"); if (!pi_target) goto error; @@ -3668,14 +3708,14 @@ _elementtree.XMLParser.__init__ * target: object = NULL - encoding: str(accept={str, NoneType}) = NULL + encoding: str(accept={str, NoneType}) = None [clinic start generated code]*/ static int _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, const char *encoding) -/*[clinic end generated code: output=3ae45ec6cdf344e4 input=96288fcba916cfce]*/ +/*[clinic end generated code: output=3ae45ec6cdf344e4 input=53e35a829ae043e8]*/ { self->entity = PyDict_New(); if (!self->entity) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index a806241897fcbd..1513e4e35edc6e 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -26,23 +26,28 @@ #include #include "openssl/err.h" -#define MUNCH_SIZE INT_MAX - #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL < 1.1.0 */ #define EVP_MD_CTX_new EVP_MD_CTX_create #define EVP_MD_CTX_free EVP_MD_CTX_destroy -#define HAS_FAST_PKCS5_PBKDF2_HMAC 0 -#include -#else -/* OpenSSL >= 1.1.0 */ -#define HAS_FAST_PKCS5_PBKDF2_HMAC 1 #endif +#define MUNCH_SIZE INT_MAX + +#ifdef NID_sha3_224 +#define PY_OPENSSL_HAS_SHA3 1 +#endif + +#if defined(EVP_MD_FLAG_XOF) && defined(NID_shake128) +#define PY_OPENSSL_HAS_SHAKE 1 +#endif + +#ifdef NID_blake2b512 +#define PY_OPENSSL_HAS_BLAKE2 1 +#endif typedef struct { PyObject_HEAD - PyObject *name; /* name of this hash algorithm */ EVP_MD_CTX *ctx; /* OpenSSL message digest context */ PyThread_type_lock lock; /* OpenSSL context lock */ } EVPobject; @@ -50,18 +55,6 @@ typedef struct { static PyTypeObject EVPtype; - -#define DEFINE_CONSTS_FOR_NEW(Name) \ - static PyObject *CONST_ ## Name ## _name_obj = NULL; \ - static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL; - -DEFINE_CONSTS_FOR_NEW(md5) -DEFINE_CONSTS_FOR_NEW(sha1) -DEFINE_CONSTS_FOR_NEW(sha224) -DEFINE_CONSTS_FOR_NEW(sha256) -DEFINE_CONSTS_FOR_NEW(sha384) -DEFINE_CONSTS_FOR_NEW(sha512) - #include "clinic/_hashopenssl.c.h" /*[clinic input] module _hashlib @@ -101,17 +94,148 @@ _setException(PyObject *exc) } /* LCOV_EXCL_STOP */ +static PyObject* +py_digest_name(const EVP_MD *md) +{ + int nid = EVP_MD_nid(md); + const char *name = NULL; + + /* 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: + /* 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 + * names for several algorithms. + */ + 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) +{ + const EVP_MD *digest = EVP_get_digestbyname(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(); + } + else if (!strcmp(name, "sha512_256") || !strcmp(name, "SHA512_256")) { + digest = EVP_sha512_256(); + } +#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 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 + } + + return digest; +} + static EVPobject * -newEVPobject(PyObject *name) +newEVPobject(void) { EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype); if (retval == NULL) { return NULL; } - /* save the name for .name to return */ - Py_INCREF(name); - retval->name = name; retval->lock = NULL; retval->ctx = EVP_MD_CTX_new(); @@ -124,7 +248,7 @@ newEVPobject(PyObject *name) return retval; } -static void +static int EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) { unsigned int process; @@ -136,11 +260,12 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int); if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) { _setException(PyExc_ValueError); - break; + return -1; } len -= process; cp += process; } + return 0; } /* Internal methods for a hash object */ @@ -151,7 +276,6 @@ EVP_dealloc(EVPobject *self) if (self->lock != NULL) PyThread_free_lock(self->lock); EVP_MD_CTX_free(self->ctx); - Py_XDECREF(self->name); PyObject_Del(self); } @@ -179,7 +303,7 @@ EVP_copy_impl(EVPobject *self) { EVPobject *newobj; - if ( (newobj = newEVPobject(self->name))==NULL) + if ( (newobj = newEVPobject())==NULL) return NULL; if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) { @@ -272,6 +396,7 @@ static PyObject * EVP_update(EVPobject *self, PyObject *obj) /*[clinic end generated code: output=ec1d55ed2432e966 input=9b30ec848f015501]*/ { + int result; Py_buffer view; GET_BUFFER_VIEW_OR_ERROUT(obj, &view); @@ -284,14 +409,17 @@ EVP_update(EVPobject *self, PyObject *obj) if (self->lock != NULL) { Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(self->lock, 1); - EVP_hash(self, view.buf, view.len); + result = EVP_hash(self, view.buf, view.len); PyThread_release_lock(self->lock); Py_END_ALLOW_THREADS } else { - EVP_hash(self, view.buf, view.len); + result = EVP_hash(self, view.buf, view.len); } PyBuffer_Release(&view); + + if (result == -1) + return NULL; Py_RETURN_NONE; } @@ -319,10 +447,11 @@ EVP_get_digest_size(EVPobject *self, void *closure) return PyLong_FromLong(size); } -static PyMemberDef EVP_members[] = { - {"name", T_OBJECT, offsetof(EVPobject, name), READONLY, PyDoc_STR("algorithm name.")}, - {NULL} /* Sentinel */ -}; +static PyObject * +EVP_get_name(EVPobject *self, void *closure) +{ + return py_digest_name(EVP_MD_CTX_md(self->ctx)); +} static PyGetSetDef EVP_getseters[] = { {"digest_size", @@ -333,6 +462,10 @@ static PyGetSetDef EVP_getseters[] = { (getter)EVP_get_block_size, NULL, NULL, NULL}, + {"name", + (getter)EVP_get_name, NULL, + NULL, + PyDoc_STR("algorithm name.")}, {NULL} /* Sentinel */ }; @@ -340,7 +473,14 @@ static PyGetSetDef EVP_getseters[] = { static PyObject * EVP_repr(EVPobject *self) { - return PyUnicode_FromFormat("<%U HASH object @ %p>", self->name, self); + PyObject *name_obj, *repr; + name_obj = py_digest_name(EVP_MD_CTX_md(self->ctx)); + if (!name_obj) { + return NULL; + } + repr = PyUnicode_FromFormat("<%U HASH object @ %p>", name_obj, self); + Py_DECREF(name_obj); + return repr; } PyDoc_STRVAR(hashtype_doc, @@ -391,7 +531,7 @@ static PyTypeObject EVPtype = { 0, /*tp_iter*/ 0, /*tp_iternext*/ EVP_methods, /* tp_methods */ - EVP_members, /* tp_members */ + NULL, /* tp_members */ EVP_getseters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ @@ -400,38 +540,39 @@ static PyTypeObject EVPtype = { 0, /* tp_dictoffset */ }; +\ static PyObject * -EVPnew(PyObject *name_obj, - const EVP_MD *digest, const EVP_MD_CTX *initial_ctx, +EVPnew(const EVP_MD *digest, const unsigned char *cp, Py_ssize_t len) { + int result = 0; EVPobject *self; - if (!digest && !initial_ctx) { + if (!digest) { PyErr_SetString(PyExc_ValueError, "unsupported hash type"); return NULL; } - if ((self = newEVPobject(name_obj)) == NULL) + if ((self = newEVPobject()) == NULL) return NULL; - if (initial_ctx) { - EVP_MD_CTX_copy(self->ctx, initial_ctx); - } else { - if (!EVP_DigestInit(self->ctx, digest)) { - _setException(PyExc_ValueError); - Py_DECREF(self); - return NULL; - } + if (!EVP_DigestInit_ex(self->ctx, digest, NULL)) { + _setException(PyExc_ValueError); + Py_DECREF(self); + return NULL; } if (cp && len) { if (len >= HASHLIB_GIL_MINSIZE) { Py_BEGIN_ALLOW_THREADS - EVP_hash(self, cp, len); + result = EVP_hash(self, cp, len); Py_END_ALLOW_THREADS } else { - EVP_hash(self, cp, len); + result = EVP_hash(self, cp, len); + } + if (result == -1) { + Py_DECREF(self); + return NULL; } } @@ -445,7 +586,7 @@ EVPnew(PyObject *name_obj, _hashlib.new as EVP_new name as name_obj: object - string as data_obj: object(py_default="b''") = NULL + string as data_obj: object(c_default="NULL") = b'' Return a new hash object using the named algorithm. @@ -457,7 +598,7 @@ The MD5 and SHA1 algorithms are always supported. static PyObject * EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj) -/*[clinic end generated code: output=9e7cf664e04b0226 input=1c46e40e0fec91f3]*/ +/*[clinic end generated code: output=9e7cf664e04b0226 input=7eb79bf30058bd02]*/ { Py_buffer view = { 0 }; PyObject *ret_obj; @@ -472,105 +613,133 @@ EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj) if (data_obj) GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); - digest = EVP_get_digestbyname(name); + digest = py_digest_by_name(name); - ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, view.len); + ret_obj = EVPnew(digest, (unsigned char*)view.buf, view.len); if (data_obj) PyBuffer_Release(&view); return ret_obj; } -#if (OPENSSL_VERSION_NUMBER >= 0x10000000 && !defined(OPENSSL_NO_HMAC) \ - && !defined(OPENSSL_NO_SHA)) +static PyObject* +EVP_fast_new(PyObject *module, PyObject *data_obj, const EVP_MD *digest) +{ + Py_buffer view = { 0 }; + PyObject *ret_obj; -#define PY_PBKDF2_HMAC 1 + if (data_obj) + GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); -#if !HAS_FAST_PKCS5_PBKDF2_HMAC -/* Improved implementation of PKCS5_PBKDF2_HMAC() - * - * PKCS5_PBKDF2_HMAC_fast() hashes the password exactly one time instead of - * `iter` times. Today (2013) the iteration count is typically 100,000 or - * more. The improved algorithm is not subject to a Denial-of-Service - * vulnerability with overly large passwords. - * - * Also OpenSSL < 1.0 don't provide PKCS5_PBKDF2_HMAC(), only - * PKCS5_PBKDF2_SHA1. - */ -static int -PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen, - const unsigned char *salt, int saltlen, - int iter, const EVP_MD *digest, - int keylen, unsigned char *out) + ret_obj = EVPnew(digest, (unsigned char*)view.buf, view.len); + + if (data_obj) + PyBuffer_Release(&view); + + return ret_obj; +} + +/*[clinic input] +_hashlib.openssl_md5 + + string as data_obj: object(py_default="b''") = NULL + +Returns a md5 hash object; optionally initialized with a string + +[clinic start generated code]*/ + +static PyObject * +_hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj) +/*[clinic end generated code: output=6caae75b73e22c3f input=52010d3869e1b1a7]*/ { - unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; - int cplen, j, k, tkeylen, mdlen; - unsigned long i = 1; - HMAC_CTX hctx_tpl, hctx; - - mdlen = EVP_MD_size(digest); - if (mdlen < 0) - return 0; - - HMAC_CTX_init(&hctx_tpl); - HMAC_CTX_init(&hctx); - p = out; - tkeylen = keylen; - if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) { - HMAC_CTX_cleanup(&hctx_tpl); - return 0; - } - while (tkeylen) { - if (tkeylen > mdlen) - cplen = mdlen; - else - cplen = tkeylen; - /* We are unlikely to ever use more than 256 blocks (5120 bits!) - * but just in case... - */ - itmp[0] = (unsigned char)((i >> 24) & 0xff); - itmp[1] = (unsigned char)((i >> 16) & 0xff); - itmp[2] = (unsigned char)((i >> 8) & 0xff); - itmp[3] = (unsigned char)(i & 0xff); - if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) { - HMAC_CTX_cleanup(&hctx_tpl); - return 0; - } - if (!HMAC_Update(&hctx, salt, saltlen) - || !HMAC_Update(&hctx, itmp, 4) - || !HMAC_Final(&hctx, digtmp, NULL)) { - HMAC_CTX_cleanup(&hctx_tpl); - HMAC_CTX_cleanup(&hctx); - return 0; - } - HMAC_CTX_cleanup(&hctx); - memcpy(p, digtmp, cplen); - for (j = 1; j < iter; j++) { - if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) { - HMAC_CTX_cleanup(&hctx_tpl); - return 0; - } - if (!HMAC_Update(&hctx, digtmp, mdlen) - || !HMAC_Final(&hctx, digtmp, NULL)) { - HMAC_CTX_cleanup(&hctx_tpl); - HMAC_CTX_cleanup(&hctx); - return 0; - } - HMAC_CTX_cleanup(&hctx); - for (k = 0; k < cplen; k++) { - p[k] ^= digtmp[k]; - } - } - tkeylen-= cplen; - i++; - p+= cplen; - } - HMAC_CTX_cleanup(&hctx_tpl); - return 1; + return EVP_fast_new(module, data_obj, EVP_md5()); } -#endif +/*[clinic input] +_hashlib.openssl_sha1 + + string as data_obj: object(py_default="b''") = NULL + +Returns a sha1 hash object; optionally initialized with a string + +[clinic start generated code]*/ + +static PyObject * +_hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj) +/*[clinic end generated code: output=07606d8f75153e61 input=16807d30e4aa8ae9]*/ +{ + return EVP_fast_new(module, data_obj, EVP_sha1()); +} + + +/*[clinic input] +_hashlib.openssl_sha224 + + string as data_obj: object(py_default="b''") = NULL + +Returns a sha224 hash object; optionally initialized with a string + +[clinic start generated code]*/ + +static PyObject * +_hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj) +/*[clinic end generated code: output=55e848761bcef0c9 input=5dbc2f1d84eb459b]*/ +{ + return EVP_fast_new(module, data_obj, EVP_sha224()); +} + + +/*[clinic input] +_hashlib.openssl_sha256 + + string as data_obj: object(py_default="b''") = NULL + +Returns a sha256 hash object; optionally initialized with a string + +[clinic start generated code]*/ + +static PyObject * +_hashlib_openssl_sha256_impl(PyObject *module, PyObject *data_obj) +/*[clinic end generated code: output=05851d7cce34ac65 input=a68a5d21cda5a80f]*/ +{ + return EVP_fast_new(module, data_obj, EVP_sha256()); +} + + +/*[clinic input] +_hashlib.openssl_sha384 + + string as data_obj: object(py_default="b''") = NULL + +Returns a sha384 hash object; optionally initialized with a string + +[clinic start generated code]*/ + +static PyObject * +_hashlib_openssl_sha384_impl(PyObject *module, PyObject *data_obj) +/*[clinic end generated code: output=5101a4704a932c2f input=6bdfa006622b64ea]*/ +{ + return EVP_fast_new(module, data_obj, EVP_sha384()); +} + + +/*[clinic input] +_hashlib.openssl_sha512 + + string as data_obj: object(py_default="b''") = NULL + +Returns a sha512 hash object; optionally initialized with a string + +[clinic start generated code]*/ + +static PyObject * +_hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj) +/*[clinic end generated code: output=20c8e63ee560a5cb input=ece50182ad4b76a6]*/ +{ + return EVP_fast_new(module, data_obj, EVP_sha512()); +} + /*[clinic input] _hashlib.pbkdf2_hmac as pbkdf2_hmac @@ -652,17 +821,10 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name, key = PyBytes_AS_STRING(key_obj); Py_BEGIN_ALLOW_THREADS -#if HAS_FAST_PKCS5_PBKDF2_HMAC retval = PKCS5_PBKDF2_HMAC((char*)password->buf, (int)password->len, (unsigned char *)salt->buf, (int)salt->len, iterations, digest, dklen, (unsigned char *)key); -#else - retval = PKCS5_PBKDF2_HMAC_fast((char*)password->buf, (int)password->len, - (unsigned char *)salt->buf, (int)salt->len, - iterations, digest, dklen, - (unsigned char *)key); -#endif Py_END_ALLOW_THREADS if (!retval) { @@ -675,8 +837,6 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name, return key_obj; } -#endif - #if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER) #define PY_SCRYPT 1 @@ -867,21 +1027,17 @@ typedef struct _internal_name_mapper_state { /* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */ static void -_openssl_hash_name_mapper(const OBJ_NAME *openssl_obj_name, void *arg) +_openssl_hash_name_mapper(const EVP_MD *md, const char *from, + const char *to, void *arg) { _InternalNameMapperState *state = (_InternalNameMapperState *)arg; PyObject *py_name; assert(state != NULL); - if (openssl_obj_name == NULL) - return; - /* Ignore aliased names, they pollute the list and OpenSSL appears to - * have its own definition of alias as the resulting list still - * contains duplicate and alternate names for several algorithms. */ - if (openssl_obj_name->alias) + if (md == NULL) return; - py_name = PyUnicode_FromString(openssl_obj_name->name); + py_name = py_digest_name(md); if (py_name == NULL) { state->error = 1; } else { @@ -903,7 +1059,7 @@ generate_hash_name_list(void) return NULL; state.error = 0; - OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, &_openssl_hash_name_mapper, &state); + EVP_MD_do_all(&_openssl_hash_name_mapper, &state); if (state.error) { Py_DECREF(state.set); @@ -912,91 +1068,19 @@ generate_hash_name_list(void) return state.set; } - -/* - * This macro generates constructor function definitions for specific - * hash algorithms. These constructors are much faster than calling - * the generic one passing it a python string and are noticeably - * faster than calling a python new() wrapper. That is important for - * code that wants to make hashes of a bunch of small strings. - * The first call will lazy-initialize, which reports an exception - * if initialization fails. - */ -#define GEN_CONSTRUCTOR(NAME) \ - static PyObject * \ - EVP_new_ ## NAME (PyObject *self, PyObject *const *args, Py_ssize_t nargs) \ - { \ - PyObject *data_obj = NULL; \ - Py_buffer view = { 0 }; \ - PyObject *ret_obj; \ - \ - if (!_PyArg_ParseStack(args, nargs, "|O:" #NAME , &data_obj)) { \ - return NULL; \ - } \ - \ - if (CONST_new_ ## NAME ## _ctx_p == NULL) { \ - EVP_MD_CTX *ctx_p = EVP_MD_CTX_new(); \ - if (!EVP_get_digestbyname(#NAME) || \ - !EVP_DigestInit(ctx_p, EVP_get_digestbyname(#NAME))) { \ - _setException(PyExc_ValueError); \ - EVP_MD_CTX_free(ctx_p); \ - return NULL; \ - } \ - CONST_new_ ## NAME ## _ctx_p = ctx_p; \ - } \ - \ - if (data_obj) \ - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); \ - \ - ret_obj = EVPnew( \ - CONST_ ## NAME ## _name_obj, \ - NULL, \ - CONST_new_ ## NAME ## _ctx_p, \ - (unsigned char*)view.buf, \ - view.len); \ - \ - if (data_obj) \ - PyBuffer_Release(&view); \ - return ret_obj; \ - } - -/* a PyMethodDef structure for the constructor */ -#define CONSTRUCTOR_METH_DEF(NAME) \ - {"openssl_" #NAME, (PyCFunction)(void(*)(void))EVP_new_ ## NAME, METH_FASTCALL, \ - PyDoc_STR("Returns a " #NAME \ - " hash object; optionally initialized with a string") \ - } - -/* used in the init function to setup a constructor: initialize OpenSSL - constructor constants if they haven't been initialized already. */ -#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \ - if (CONST_ ## NAME ## _name_obj == NULL) { \ - CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \ - } \ -} while (0); - -GEN_CONSTRUCTOR(md5) -GEN_CONSTRUCTOR(sha1) -GEN_CONSTRUCTOR(sha224) -GEN_CONSTRUCTOR(sha256) -GEN_CONSTRUCTOR(sha384) -GEN_CONSTRUCTOR(sha512) - /* List of functions exported by this module */ static struct PyMethodDef EVP_functions[] = { EVP_NEW_METHODDEF -#ifdef PY_PBKDF2_HMAC PBKDF2_HMAC_METHODDEF -#endif _HASHLIB_SCRYPT_METHODDEF _HASHLIB_HMAC_DIGEST_METHODDEF - CONSTRUCTOR_METH_DEF(md5), - CONSTRUCTOR_METH_DEF(sha1), - CONSTRUCTOR_METH_DEF(sha224), - CONSTRUCTOR_METH_DEF(sha256), - CONSTRUCTOR_METH_DEF(sha384), - CONSTRUCTOR_METH_DEF(sha512), + _HASHLIB_OPENSSL_MD5_METHODDEF + _HASHLIB_OPENSSL_SHA1_METHODDEF + _HASHLIB_OPENSSL_SHA224_METHODDEF + _HASHLIB_OPENSSL_SHA256_METHODDEF + _HASHLIB_OPENSSL_SHA384_METHODDEF + _HASHLIB_OPENSSL_SHA512_METHODDEF {NULL, NULL} /* Sentinel */ }; @@ -1021,7 +1105,7 @@ PyInit__hashlib(void) { PyObject *m, *openssl_md_meth_names; -#ifndef OPENSSL_VERSION_1_1 +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) /* Load all digest algorithms and initialize cpuid */ OPENSSL_add_all_algorithms_noconf(); ERR_load_crypto_strings(); @@ -1053,12 +1137,5 @@ PyInit__hashlib(void) Py_INCREF((PyObject *)&EVPtype); PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype); - /* these constants are used by the convenience constructors */ - INIT_CONSTRUCTOR_CONSTANTS(md5); - INIT_CONSTRUCTOR_CONSTANTS(sha1); - INIT_CONSTRUCTOR_CONSTANTS(sha224); - INIT_CONSTRUCTOR_CONSTANTS(sha256); - INIT_CONSTRUCTOR_CONSTANTS(sha384); - INIT_CONSTRUCTOR_CONSTANTS(sha512); return m; } diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 5c2f019e840bdf..49ed2cb00de52f 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -103,9 +103,9 @@ _io.open file: object mode: str = "r" buffering: int = -1 - encoding: str(accept={str, NoneType}) = NULL - errors: str(accept={str, NoneType}) = NULL - newline: str(accept={str, NoneType}) = NULL + encoding: str(accept={str, NoneType}) = None + errors: str(accept={str, NoneType}) = None + newline: str(accept={str, NoneType}) = None closefd: bool(accept={int}) = True opener: object = None @@ -233,7 +233,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=03da2940c8a65871]*/ +/*[clinic end generated code: output=aefafc4ce2b46dc0 input=7295902222e6b311]*/ { unsigned i; diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 44e12db6a30ed0..8e8ff97ff8c676 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -1378,12 +1378,14 @@ buffered_repr(buffered *self) { PyObject *nameobj, *res; - nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name); - if (nameobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_Exception)) - PyErr_Clear(); - else + if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) { + if (!PyErr_ExceptionMatches(PyExc_ValueError)) { return NULL; + } + /* Ignore ValueError raised if the underlying stream was detached */ + PyErr_Clear(); + } + if (nameobj == NULL) { res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name); } else { diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 19e1ed8441e3f3..3cf6402e75f7d5 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -818,7 +818,7 @@ bytesio_setstate(bytesio *self, PyObject *state) /* Set carefully the position value. Alternatively, we could use the seek method instead of modifying self->pos directly to better protect the - object internal state against errneous (or malicious) inputs. */ + object internal state against erroneous (or malicious) inputs. */ position_obj = PyTuple_GET_ITEM(state, 1); if (!PyLong_Check(position_obj)) { PyErr_Format(PyExc_TypeError, diff --git a/Modules/_io/clinic/_iomodule.c.h b/Modules/_io/clinic/_iomodule.c.h index 00ad616b41fe6e..1a9651d340813f 100644 --- a/Modules/_io/clinic/_iomodule.c.h +++ b/Modules/_io/clinic/_iomodule.c.h @@ -161,7 +161,7 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw } if (args[1]) { if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("open", 2, "str", args[1]); + _PyArg_BadArgument("open", "argument 'mode'", "str", args[1]); goto exit; } Py_ssize_t mode_length; @@ -207,7 +207,7 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw } } else { - _PyArg_BadArgument("open", 4, "str or None", args[3]); + _PyArg_BadArgument("open", "argument 'encoding'", "str or None", args[3]); goto exit; } if (!--noptargs) { @@ -230,7 +230,7 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw } } else { - _PyArg_BadArgument("open", 5, "str or None", args[4]); + _PyArg_BadArgument("open", "argument 'errors'", "str or None", args[4]); goto exit; } if (!--noptargs) { @@ -253,7 +253,7 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw } } else { - _PyArg_BadArgument("open", 6, "str or None", args[5]); + _PyArg_BadArgument("open", "argument 'newline'", "str or None", args[5]); goto exit; } if (!--noptargs) { @@ -311,7 +311,7 @@ _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("open_code", 1, "str", args[0]); + _PyArg_BadArgument("open_code", "argument 'path'", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -323,4 +323,4 @@ _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=d479285078750d68 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3df6bc6d91697545 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index d5e8c8a74813c5..72841fcb6779c7 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -21,11 +21,11 @@ _io__BufferedIOBase_readinto(PyObject *self, PyObject *arg) if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); - _PyArg_BadArgument("readinto", 0, "read-write bytes-like object", arg); + _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto", 0, "contiguous buffer", arg); + _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); goto exit; } return_value = _io__BufferedIOBase_readinto_impl(self, &buffer); @@ -58,11 +58,11 @@ _io__BufferedIOBase_readinto1(PyObject *self, PyObject *arg) if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); - _PyArg_BadArgument("readinto1", 0, "read-write bytes-like object", arg); + _PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg); goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto1", 0, "contiguous buffer", arg); + _PyArg_BadArgument("readinto1", "argument", "contiguous buffer", arg); goto exit; } return_value = _io__BufferedIOBase_readinto1_impl(self, &buffer); @@ -243,11 +243,11 @@ _io__Buffered_readinto(buffered *self, PyObject *arg) if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); - _PyArg_BadArgument("readinto", 0, "read-write bytes-like object", arg); + _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto", 0, "contiguous buffer", arg); + _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); goto exit; } return_value = _io__Buffered_readinto_impl(self, &buffer); @@ -280,11 +280,11 @@ _io__Buffered_readinto1(buffered *self, PyObject *arg) if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); - _PyArg_BadArgument("readinto1", 0, "read-write bytes-like object", arg); + _PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg); goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto1", 0, "contiguous buffer", arg); + _PyArg_BadArgument("readinto1", "argument", "contiguous buffer", arg); goto exit; } return_value = _io__Buffered_readinto1_impl(self, &buffer); @@ -538,7 +538,7 @@ _io_BufferedWriter_write(buffered *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("write", 0, "contiguous buffer", arg); + _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); goto exit; } return_value = _io_BufferedWriter_write_impl(self, &buffer); @@ -672,4 +672,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=b22b4aedd53c340a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7246104f6c7d3167 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index 8dd68f56137f09..83cd490dc59804 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -319,11 +319,11 @@ _io_BytesIO_readinto(bytesio *self, PyObject *arg) if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); - _PyArg_BadArgument("readinto", 0, "read-write bytes-like object", arg); + _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto", 0, "contiguous buffer", arg); + _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); goto exit; } return_value = _io_BytesIO_readinto_impl(self, &buffer); @@ -515,4 +515,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=22e8fb54874b6ee5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4ec2506def9c8eb9 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h index 8016e988862464..53e7067cf7a741 100644 --- a/Modules/_io/clinic/fileio.c.h +++ b/Modules/_io/clinic/fileio.c.h @@ -70,7 +70,7 @@ _io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) } if (fastargs[1]) { if (!PyUnicode_Check(fastargs[1])) { - _PyArg_BadArgument("FileIO", 2, "str", fastargs[1]); + _PyArg_BadArgument("FileIO", "argument 'mode'", "str", fastargs[1]); goto exit; } Py_ssize_t mode_length; @@ -200,11 +200,11 @@ _io_FileIO_readinto(fileio *self, PyObject *arg) if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); - _PyArg_BadArgument("readinto", 0, "read-write bytes-like object", arg); + _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto", 0, "contiguous buffer", arg); + _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); goto exit; } return_value = _io_FileIO_readinto_impl(self, &buffer); @@ -303,7 +303,7 @@ _io_FileIO_write(fileio *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&b, 'C')) { - _PyArg_BadArgument("write", 0, "contiguous buffer", arg); + _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); goto exit; } return_value = _io_FileIO_write_impl(self, &b); @@ -408,7 +408,7 @@ static PyObject * _io_FileIO_truncate(fileio *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *posobj = NULL; + PyObject *posobj = Py_None; if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { goto exit; @@ -447,4 +447,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=7ee4f3ae584fc6d2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e7682d0a3264d284 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index cec9defea0250e..b8b507543ea81c 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -229,7 +229,7 @@ _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) } } else { - _PyArg_BadArgument("TextIOWrapper", 2, "str or None", fastargs[1]); + _PyArg_BadArgument("TextIOWrapper", "argument 'encoding'", "str or None", fastargs[1]); goto exit; } if (!--noptargs) { @@ -258,7 +258,7 @@ _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) } } else { - _PyArg_BadArgument("TextIOWrapper", 4, "str or None", fastargs[3]); + _PyArg_BadArgument("TextIOWrapper", "argument 'newline'", "str or None", fastargs[3]); goto exit; } if (!--noptargs) { @@ -401,7 +401,7 @@ _io_TextIOWrapper_write(textio *self, PyObject *arg) PyObject *text; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("write", 0, "str", arg); + _PyArg_BadArgument("write", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -701,4 +701,4 @@ _io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) { return _io_TextIOWrapper_close_impl(self); } -/*[clinic end generated code: output=b651e056e3000f88 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b1bae4f4cdf6019e input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/winconsoleio.c.h b/Modules/_io/clinic/winconsoleio.c.h index bb0cdc4558dd86..3e501a58537165 100644 --- a/Modules/_io/clinic/winconsoleio.c.h +++ b/Modules/_io/clinic/winconsoleio.c.h @@ -69,7 +69,7 @@ _io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) } if (fastargs[1]) { if (!PyUnicode_Check(fastargs[1])) { - _PyArg_BadArgument("_WindowsConsoleIO", 2, "str", fastargs[1]); + _PyArg_BadArgument("_WindowsConsoleIO", "argument 'mode'", "str", fastargs[1]); goto exit; } Py_ssize_t mode_length; @@ -200,11 +200,11 @@ _io__WindowsConsoleIO_readinto(winconsoleio *self, PyObject *arg) if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); - _PyArg_BadArgument("readinto", 0, "read-write bytes-like object", arg); + _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto", 0, "contiguous buffer", arg); + _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); goto exit; } return_value = _io__WindowsConsoleIO_readinto_impl(self, &buffer); @@ -313,7 +313,7 @@ _io__WindowsConsoleIO_write(winconsoleio *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&b, 'C')) { - _PyArg_BadArgument("write", 0, "contiguous buffer", arg); + _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); goto exit; } return_value = _io__WindowsConsoleIO_write_impl(self, &b); @@ -386,4 +386,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=57bf2c09a42bd330 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f5b8860a658a001a input=a9049054013a1b77]*/ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 7f784a34c30d33..9166c607e737c6 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -979,7 +979,7 @@ _io_FileIO_tell_impl(fileio *self) #ifdef HAVE_FTRUNCATE /*[clinic input] _io.FileIO.truncate - size as posobj: object = NULL + size as posobj: object = None / Truncate the file to at most size bytes and return the truncated size. @@ -990,7 +990,7 @@ The current file position is changed to the value of size. static PyObject * _io_FileIO_truncate_impl(fileio *self, PyObject *posobj) -/*[clinic end generated code: output=e49ca7a916c176fa input=9026af44686b7318]*/ +/*[clinic end generated code: output=e49ca7a916c176fa input=b0ac133939823875]*/ { Py_off_t pos; int ret; @@ -1002,7 +1002,7 @@ _io_FileIO_truncate_impl(fileio *self, PyObject *posobj) if (!self->writable) return err_mode("writing"); - if (posobj == Py_None || posobj == NULL) { + if (posobj == Py_None) { /* Get the current position. */ posobj = portable_lseek(self, NULL, 1); if (posobj == NULL) diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 9e9724db2d3308..8b5fa7a369f38c 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -899,7 +899,7 @@ stringio_setstate(stringio *self, PyObject *state) /* Set carefully the position value. Alternatively, we could use the seek method instead of modifying self->pos directly to better protect the - object internal state against errneous (or malicious) inputs. */ + object internal state against erroneous (or malicious) inputs. */ position_obj = PyTuple_GET_ITEM(state, 2); if (!PyLong_Check(position_obj)) { PyErr_Format(PyExc_TypeError, diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 73b2756afce5e6..2f4a5245681f0b 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -991,9 +991,9 @@ _textiowrapper_fix_encoder_state(textio *self) /*[clinic input] _io.TextIOWrapper.__init__ buffer: object - encoding: str(accept={str, NoneType}) = NULL + encoding: str(accept={str, NoneType}) = None errors: object = None - newline: str(accept={str, NoneType}) = NULL + newline: str(accept={str, NoneType}) = None line_buffering: bool(accept={int}) = False write_through: bool(accept={int}) = False @@ -1032,7 +1032,7 @@ _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=1c5dd5d78bfcc675]*/ +/*[clinic end generated code: output=72267c0c01032ed2 input=77d8696d1a1f460b]*/ { PyObject *raw, *codec_info = NULL; _PyIO_State *state = NULL; @@ -2860,14 +2860,14 @@ textiowrapper_repr(textio *self) } goto error; } - nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name); - if (nameobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_Exception)) - PyErr_Clear(); - else + if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) { + if (!PyErr_ExceptionMatches(PyExc_ValueError)) { goto error; + } + /* Ignore ValueError raised if the underlying stream was detached */ + PyErr_Clear(); } - else { + if (nameobj != NULL) { s = PyUnicode_FromFormat(" name=%R", nameobj); Py_DECREF(nameobj); if (s == NULL) @@ -2876,14 +2876,10 @@ textiowrapper_repr(textio *self) if (res == NULL) goto error; } - modeobj = _PyObject_GetAttrId((PyObject *) self, &PyId_mode); - if (modeobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_Exception)) - PyErr_Clear(); - else - goto error; + if (_PyObject_LookupAttrId((PyObject *) self, &PyId_mode, &modeobj) < 0) { + goto error; } - else { + if (modeobj != NULL) { s = PyUnicode_FromFormat(" mode=%R", modeobj); Py_DECREF(modeobj); if (s == NULL) diff --git a/Modules/_json.c b/Modules/_json.c index e3aa997598fc2e..048a9654ce18ca 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -439,7 +439,7 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next if (c == '"' || c == '\\') { break; } - else if (strict && c <= 0x1f) { + else if (c <= 0x1f && strict) { raise_errmsg("Invalid control character at", pystr, next); goto bail; } diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index 9e68cbb78af50d..1ab67f306b73a0 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -872,9 +872,6 @@ decompress_buf(Decompressor *d, Py_ssize_t max_length) PyObject *result; lzma_stream *lzs = &d->lzs; - if (lzs->avail_in == 0) - return PyBytes_FromStringAndSize(NULL, 0); - if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE) result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); else @@ -891,7 +888,10 @@ decompress_buf(Decompressor *d, Py_ssize_t max_length) Py_BEGIN_ALLOW_THREADS lzret = lzma_code(lzs, LZMA_RUN); data_size = (char *)lzs->next_out - PyBytes_AS_STRING(result); + if (lzret == LZMA_BUF_ERROR && lzs->avail_in == 0 && lzs->avail_out > 0) + lzret = LZMA_OK; /* That wasn't a real error */ Py_END_ALLOW_THREADS + if (catch_lzma_error(lzret)) goto error; if (lzret == LZMA_GET_CHECK || lzret == LZMA_NO_CHECK) @@ -899,15 +899,19 @@ decompress_buf(Decompressor *d, Py_ssize_t max_length) if (lzret == LZMA_STREAM_END) { d->eof = 1; break; - } else if (lzs->avail_in == 0) { - break; } else if (lzs->avail_out == 0) { + /* Need to check lzs->avail_out before lzs->avail_in. + Maybe lzs's internal state still have a few bytes + can be output, grow the output buffer and continue + if max_lengh < 0. */ if (data_size == max_length) break; if (grow_buffer(&result, max_length) == -1) goto error; lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size; lzs->avail_out = PyBytes_GET_SIZE(result) - data_size; + } else if (lzs->avail_in == 0) { + break; } } if (data_size != PyBytes_GET_SIZE(result)) @@ -990,7 +994,19 @@ decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length) } else if (lzs->avail_in == 0) { lzs->next_in = NULL; - d->needs_input = 1; + + if (lzs->avail_out == 0) { + /* (avail_in==0 && avail_out==0) + Maybe lzs's internal state still have a few bytes can + be output, try to output them next time. */ + d->needs_input = 0; + + /* if max_length < 0, lzs->avail_out always > 0 */ + assert(max_length >= 0); + } else { + /* Input buffer exhausted, output buffer has space. */ + d->needs_input = 1; + } } else { d->needs_input = 0; diff --git a/Modules/_multiprocessing/clinic/posixshmem.c.h b/Modules/_multiprocessing/clinic/posixshmem.c.h index 0ebfa2fe3789d1..a99f0d2aae1dcb 100644 --- a/Modules/_multiprocessing/clinic/posixshmem.c.h +++ b/Modules/_multiprocessing/clinic/posixshmem.c.h @@ -35,7 +35,7 @@ _posixshmem_shm_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("shm_open", 1, "str", args[0]); + _PyArg_BadArgument("shm_open", "argument 'path'", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -108,7 +108,7 @@ _posixshmem_shm_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("shm_unlink", 1, "str", args[0]); + _PyArg_BadArgument("shm_unlink", "argument 'path'", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -130,4 +130,4 @@ _posixshmem_shm_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs #ifndef _POSIXSHMEM_SHM_UNLINK_METHODDEF #define _POSIXSHMEM_SHM_UNLINK_METHODDEF #endif /* !defined(_POSIXSHMEM_SHM_UNLINK_METHODDEF) */ -/*[clinic end generated code: output=be42e23c18677c0f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9132861c61d8c2d8 input=a9049054013a1b77]*/ diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 34e11bd5f820cd..8ee7d8ee2a7931 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -1142,7 +1142,7 @@ _Pickler_SetProtocol(PicklerObject *self, PyObject *protocol, int fix_imports) { long proto; - if (protocol == NULL || protocol == Py_None) { + if (protocol == Py_None) { proto = DEFAULT_PROTOCOL; } else { @@ -1653,7 +1653,7 @@ _Unpickler_SetInputEncoding(UnpicklerObject *self, static int _Unpickler_SetBuffers(UnpicklerObject *self, PyObject *buffers) { - if (buffers == NULL) { + if (buffers == NULL || buffers == Py_None) { self->buffers = NULL; } else { @@ -2119,7 +2119,7 @@ save_long(PicklerObject *self, PyObject *obj) /* How many bytes do we need? There are nbits >> 3 full * bytes of data, and nbits & 7 leftover bits. If there * are any leftover bits, then we clearly need another - * byte. Wnat's not so obvious is that we *probably* + * byte. What's not so obvious is that we *probably* * need another byte even if there aren't any leftovers: * the most-significant bit of the most-significant byte * acts like a sign bit, and it's usually got a sense @@ -4385,7 +4385,6 @@ save(PicklerObject *self, PyObject *obj, int pers_save) _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 @@ -4406,14 +4405,15 @@ save(PicklerObject *self, PyObject *obj, int pers_save) } } else { - PickleState *st = _Pickle_GetGlobalState(); - /* Check for a __reduce__ method. */ - reduce_func = _PyObject_GetAttrId(obj, &PyId___reduce__); + if (_PyObject_LookupAttrId(obj, &PyId___reduce__, &reduce_func) < 0) { + goto error; + } if (reduce_func != NULL) { reduce_value = _PyObject_CallNoArg(reduce_func); } else { + PickleState *st = _Pickle_GetGlobalState(); PyErr_Format(st->PicklingError, "can't pickle '%.200s' object: %R", type->tp_name, obj); @@ -4640,9 +4640,9 @@ Pickler_clear(PicklerObject *self) _pickle.Pickler.__init__ file: object - protocol: object = NULL + protocol: object = None fix_imports: bool = True - buffer_callback: object = NULL + buffer_callback: object = None This takes a binary file for writing a pickle data stream. @@ -4680,7 +4680,7 @@ static int _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports, PyObject *buffer_callback) -/*[clinic end generated code: output=0abedc50590d259b input=9a43a1c50ab91652]*/ +/*[clinic end generated code: output=0abedc50590d259b input=bb886e00443a7811]*/ { _Py_IDENTIFIER(persistent_id); _Py_IDENTIFIER(dispatch_table); @@ -6448,7 +6448,9 @@ do_append(UnpicklerObject *self, Py_ssize_t x) PyObject *extend_func; _Py_IDENTIFIER(extend); - extend_func = _PyObject_GetAttrId(list, &PyId_extend); + if (_PyObject_LookupAttrId(list, &PyId_extend, &extend_func) < 0) { + return -1; + } if (extend_func != NULL) { slice = Pdata_poplist(self->stack, x); if (!slice) { @@ -6468,7 +6470,6 @@ do_append(UnpicklerObject *self, Py_ssize_t x) /* Even if the PEP 307 requires extend() and append() methods, fall back on append() if the object has no extend() method for backward compatibility. */ - PyErr_Clear(); append_func = _PyObject_GetAttrId(list, &PyId_append); if (append_func == NULL) return -1; @@ -7201,7 +7202,7 @@ _pickle.Unpickler.__init__ fix_imports: bool = True encoding: str = 'ASCII' errors: str = 'strict' - buffers: object = NULL + buffers: object(c_default="NULL") = () This takes a binary file for reading a pickle data stream. @@ -7229,7 +7230,7 @@ static int _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors, PyObject *buffers) -/*[clinic end generated code: output=09f0192649ea3f85 input=da4b62d9edb68700]*/ +/*[clinic end generated code: output=09f0192649ea3f85 input=ca4c1faea9553121]*/ { _Py_IDENTIFIER(persistent_load); @@ -7621,10 +7622,10 @@ _pickle.dump obj: object file: object - protocol: object = NULL + protocol: object = None * fix_imports: bool = True - buffer_callback: object = NULL + buffer_callback: object = None Write a pickled representation of obj to the open file object file. @@ -7659,7 +7660,7 @@ static PyObject * _pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports, PyObject *buffer_callback) -/*[clinic end generated code: output=706186dba996490c input=2f035f02cc0f9547]*/ +/*[clinic end generated code: output=706186dba996490c input=cfdcaf573ed6e46c]*/ { PicklerObject *pickler = _Pickler_New(); @@ -7694,10 +7695,10 @@ _pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, _pickle.dumps obj: object - protocol: object = NULL + protocol: object = None * fix_imports: bool = True - buffer_callback: object = NULL + buffer_callback: object = None Return the pickled representation of the object as a bytes object. @@ -7723,7 +7724,7 @@ into *file* as part of the pickle stream. It is an error if static PyObject * _pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, int fix_imports, PyObject *buffer_callback) -/*[clinic end generated code: output=fbab0093a5580fdf input=001f167df711b9f1]*/ +/*[clinic end generated code: output=fbab0093a5580fdf input=9f334d535ff7194f]*/ { PyObject *result; PicklerObject *pickler = _Pickler_New(); @@ -7758,7 +7759,7 @@ _pickle.load fix_imports: bool = True encoding: str = 'ASCII' errors: str = 'strict' - buffers: object = NULL + buffers: object(c_default="NULL") = () Read and return an object from the pickle data stored in a file. @@ -7789,7 +7790,7 @@ static PyObject * _pickle_load_impl(PyObject *module, PyObject *file, int fix_imports, const char *encoding, const char *errors, PyObject *buffers) -/*[clinic end generated code: output=250452d141c23e76 input=29fae982fe778156]*/ +/*[clinic end generated code: output=250452d141c23e76 input=46c7c31c92f4f371]*/ { PyObject *result; UnpicklerObject *unpickler = _Unpickler_New(); @@ -7826,7 +7827,7 @@ _pickle.loads fix_imports: bool = True encoding: str = 'ASCII' errors: str = 'strict' - buffers: object = NULL + buffers: object(c_default="NULL") = () Read and return an object from the given pickle data. @@ -7848,7 +7849,7 @@ static PyObject * _pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports, const char *encoding, const char *errors, PyObject *buffers) -/*[clinic end generated code: output=82ac1e6b588e6d02 input=c6004393f8276867]*/ +/*[clinic end generated code: output=82ac1e6b588e6d02 input=9c2ab6a0960185ea]*/ { PyObject *result; UnpicklerObject *unpickler = _Unpickler_New(); diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index 81a23c6d330037..e693e532069079 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -583,8 +583,10 @@ subprocess_fork_exec(PyObject* self, PyObject *args) &restore_signals, &call_setsid, &preexec_fn)) return NULL; - if (_PyInterpreterState_Get() != PyInterpreterState_Main()) { - PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); + if ((preexec_fn != Py_None) && + (_PyInterpreterState_Get() != PyInterpreterState_Main())) { + PyErr_SetString(PyExc_RuntimeError, + "preexec_fn not supported within subinterpreters"); return NULL; } diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 0d6462ef7dc290..ebe073f644aa50 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -186,10 +186,9 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject } self->check_same_thread = check_same_thread; - Py_XSETREF(self->function_pinboard, PyDict_New()); - if (!self->function_pinboard) { - return -1; - } + self->function_pinboard_trace_callback = NULL; + self->function_pinboard_progress_handler = NULL; + self->function_pinboard_authorizer_cb = NULL; Py_XSETREF(self->collations, PyDict_New()); if (!self->collations) { @@ -249,19 +248,18 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self) /* Clean up if user has not called .close() explicitly. */ if (self->db) { - Py_BEGIN_ALLOW_THREADS SQLITE3_CLOSE(self->db); - Py_END_ALLOW_THREADS } Py_XDECREF(self->isolation_level); - Py_XDECREF(self->function_pinboard); + Py_XDECREF(self->function_pinboard_trace_callback); + Py_XDECREF(self->function_pinboard_progress_handler); + Py_XDECREF(self->function_pinboard_authorizer_cb); Py_XDECREF(self->row_factory); Py_XDECREF(self->text_factory); Py_XDECREF(self->collations); Py_XDECREF(self->statements); Py_XDECREF(self->cursors); - Py_TYPE(self)->tp_free((PyObject*)self); } @@ -342,9 +340,7 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args) pysqlite_do_all_statements(self, ACTION_FINALIZE, 1); if (self->db) { - Py_BEGIN_ALLOW_THREADS rc = SQLITE3_CLOSE(self->db); - Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); @@ -808,6 +804,11 @@ static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self) Py_SETREF(self->cursors, new_list); } +static void _destructor(void* args) +{ + Py_DECREF((PyObject*)args); +} + PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = {"name", "narg", "func", "deterministic", NULL}; @@ -843,17 +844,16 @@ PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObjec flags |= SQLITE_DETERMINISTIC; #endif } - if (PyDict_SetItem(self->function_pinboard, func, Py_None) == -1) { - return NULL; - } - rc = sqlite3_create_function(self->db, - name, - narg, - flags, - (void*)func, - _pysqlite_func_callback, - NULL, - NULL); + Py_INCREF(func); + rc = sqlite3_create_function_v2(self->db, + name, + narg, + flags, + (void*)func, + _pysqlite_func_callback, + NULL, + NULL, + &_destructor); // will decref func if (rc != SQLITE_OK) { /* Workaround for SQLite bug: no error code or string is available here */ @@ -880,11 +880,16 @@ PyObject* pysqlite_connection_create_aggregate(pysqlite_Connection* self, PyObje kwlist, &name, &n_arg, &aggregate_class)) { return NULL; } - - if (PyDict_SetItem(self->function_pinboard, aggregate_class, Py_None) == -1) { - return NULL; - } - rc = sqlite3_create_function(self->db, name, n_arg, SQLITE_UTF8, (void*)aggregate_class, 0, &_pysqlite_step_callback, &_pysqlite_final_callback); + Py_INCREF(aggregate_class); + rc = sqlite3_create_function_v2(self->db, + name, + n_arg, + SQLITE_UTF8, + (void*)aggregate_class, + 0, + &_pysqlite_step_callback, + &_pysqlite_final_callback, + &_destructor); // will decref func if (rc != SQLITE_OK) { /* Workaround for SQLite bug: no error code or string is available here */ PyErr_SetString(pysqlite_OperationalError, "Error creating aggregate"); @@ -1003,13 +1008,14 @@ static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, P return NULL; } - if (PyDict_SetItem(self->function_pinboard, authorizer_cb, Py_None) == -1) { - return NULL; - } rc = sqlite3_set_authorizer(self->db, _authorizer_callback, (void*)authorizer_cb); if (rc != SQLITE_OK) { PyErr_SetString(pysqlite_OperationalError, "Error setting authorizer callback"); + Py_XSETREF(self->function_pinboard_authorizer_cb, NULL); return NULL; + } else { + Py_INCREF(authorizer_cb); + Py_XSETREF(self->function_pinboard_authorizer_cb, authorizer_cb); } Py_RETURN_NONE; } @@ -1033,12 +1039,12 @@ static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* s if (progress_handler == Py_None) { /* None clears the progress handler previously set */ sqlite3_progress_handler(self->db, 0, 0, (void*)0); + Py_XSETREF(self->function_pinboard_progress_handler, NULL); } else { - if (PyDict_SetItem(self->function_pinboard, progress_handler, Py_None) == -1) - return NULL; sqlite3_progress_handler(self->db, n, _progress_handler, progress_handler); + Py_INCREF(progress_handler); + Py_XSETREF(self->function_pinboard_progress_handler, progress_handler); } - Py_RETURN_NONE; } @@ -1060,10 +1066,11 @@ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* sel if (trace_callback == Py_None) { /* None clears the trace callback previously set */ sqlite3_trace(self->db, 0, (void*)0); + Py_XSETREF(self->function_pinboard_trace_callback, NULL); } else { - if (PyDict_SetItem(self->function_pinboard, trace_callback, Py_None) == -1) - return NULL; sqlite3_trace(self->db, _trace_callback, trace_callback); + Py_INCREF(trace_callback); + Py_XSETREF(self->function_pinboard_trace_callback, trace_callback); } Py_RETURN_NONE; diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 4e9d94c5f30891..206085e00a00c7 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -85,11 +85,10 @@ typedef struct */ PyObject* text_factory; - /* remember references to functions/classes used in - * create_function/create/aggregate, use these as dictionary keys, so we - * can keep the total system refcount constant by clearing that dictionary - * in connection_dealloc */ - PyObject* function_pinboard; + /* remember references to object used in trace_callback/progress_handler/authorizer_cb */ + PyObject* function_pinboard_trace_callback; + PyObject* function_pinboard_progress_handler; + PyObject* function_pinboard_authorizer_cb; /* a dictionary of registered collation name => collation callable mappings */ PyObject* collations; diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index c487ba98908b34..9fe0dc952f0b82 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -85,6 +85,10 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* factory = (PyObject*)&pysqlite_ConnectionType; } + if (PySys_Audit("sqlite3.connect", "O", database) < 0) { + return NULL; + } + result = PyObject_Call(factory, args, kwargs); return result; diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index 5c2f40082402e3..4b47108278a0ab 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -76,16 +76,38 @@ PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx) return item; } +static int +equal_ignore_case(PyObject *left, PyObject *right) +{ + int eq = PyObject_RichCompareBool(left, right, Py_EQ); + if (eq) { /* equal or error */ + return eq; + } + if (!PyUnicode_Check(left) || !PyUnicode_Check(right)) { + return 0; + } + if (!PyUnicode_IS_ASCII(left) || !PyUnicode_IS_ASCII(right)) { + return 0; + } + + Py_ssize_t len = PyUnicode_GET_LENGTH(left); + if (PyUnicode_GET_LENGTH(right) != len) { + return 0; + } + const Py_UCS1 *p1 = PyUnicode_1BYTE_DATA(left); + const Py_UCS1 *p2 = PyUnicode_1BYTE_DATA(right); + for (; len; len--, p1++, p2++) { + if (Py_TOLOWER(*p1) != Py_TOLOWER(*p2)) { + return 0; + } + } + return 1; +} + PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) { Py_ssize_t _idx; - const char *key; Py_ssize_t nitems, i; - const char *compare_key; - - const char *p1; - const char *p2; - PyObject* item; if (PyLong_Check(idx)) { @@ -98,44 +120,22 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) Py_XINCREF(item); return item; } else if (PyUnicode_Check(idx)) { - key = PyUnicode_AsUTF8(idx); - if (key == NULL) - return NULL; - nitems = PyTuple_Size(self->description); for (i = 0; i < nitems; i++) { PyObject *obj; obj = PyTuple_GET_ITEM(self->description, i); obj = PyTuple_GET_ITEM(obj, 0); - compare_key = PyUnicode_AsUTF8(obj); - if (!compare_key) { + int eq = equal_ignore_case(idx, obj); + if (eq < 0) { return NULL; } - - p1 = key; - p2 = compare_key; - - while (1) { - if ((*p1 == (char)0) || (*p2 == (char)0)) { - break; - } - - if ((*p1 | 0x20) != (*p2 | 0x20)) { - break; - } - - p1++; - p2++; - } - - if ((*p1 == (char)0) && (*p2 == (char)0)) { + if (eq) { /* found item */ item = PyTuple_GetItem(self->data, i); Py_INCREF(item); return item; } - } PyErr_SetString(PyExc_IndexError, "No item with that key"); @@ -192,14 +192,16 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, if (opid != Py_EQ && opid != Py_NE) Py_RETURN_NOTIMPLEMENTED; - if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) { + if (PyObject_TypeCheck(_other, &pysqlite_RowType)) { pysqlite_Row *other = (pysqlite_Row *)_other; - PyObject *res = PyObject_RichCompare(self->description, other->description, opid); - if ((opid == Py_EQ && res == Py_True) - || (opid == Py_NE && res == Py_False)) { - Py_DECREF(res); + int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ); + if (eq < 0) { + return NULL; + } + if (eq) { return PyObject_RichCompare(self->data, other->data, opid); } + return PyBool_FromLong(opid != Py_EQ); } Py_RETURN_NOTIMPLEMENTED; } diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 2331c58ad77d5a..6f1f9c881530f0 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -963,6 +963,26 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, SSL_set_mode(self->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_AUTO_RETRY); +#ifdef TLS1_3_VERSION + if (sslctx->post_handshake_auth == 1) { + if (socket_type == PY_SSL_SERVER) { + /* bpo-37428: OpenSSL does not ignore SSL_VERIFY_POST_HANDSHAKE. + * Set SSL_VERIFY_POST_HANDSHAKE flag only for server sockets and + * only in combination with SSL_VERIFY_PEER flag. */ + int mode = SSL_get_verify_mode(self->ssl); + if (mode & SSL_VERIFY_PEER) { + int (*verify_cb)(int, X509_STORE_CTX *) = NULL; + verify_cb = SSL_get_verify_callback(self->ssl); + mode |= SSL_VERIFY_POST_HANDSHAKE; + SSL_set_verify(self->ssl, mode, verify_cb); + } + } else { + /* client socket */ + SSL_set_post_handshake_auth(self->ssl, 1); + } + } +#endif + if (server_hostname != NULL) { if (_ssl_configure_hostname(self, server_hostname) < 0) { Py_DECREF(self); @@ -1802,7 +1822,7 @@ _ssl__test_decode_cert_impl(PyObject *module, PyObject *path) goto fail0; } - x = PEM_read_bio_X509_AUX(cert,NULL, NULL, NULL); + x = PEM_read_bio_X509(cert, NULL, NULL, NULL); if (x == NULL) { PyErr_SetString(PySSLErrorObject, "Error decoding PEM-encoded file"); @@ -2986,10 +3006,10 @@ _set_verify_mode(PySSLContext *self, enum py_ssl_cert_requirements n) "invalid value for verify_mode"); return -1; } -#ifdef TLS1_3_VERSION - if (self->post_handshake_auth) - mode |= SSL_VERIFY_POST_HANDSHAKE; -#endif + + /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for + * server sockets and SSL_set_post_handshake_auth() for client. */ + /* keep current verify cb */ verify_cb = SSL_CTX_get_verify_callback(self->ctx); SSL_CTX_set_verify(self->ctx, mode, verify_cb); @@ -3621,7 +3641,7 @@ set_maximum_version(PySSLContext *self, PyObject *arg, void *c) static PyObject * get_num_tickets(PySSLContext *self, void *c) { - return PyLong_FromLong(SSL_CTX_get_num_tickets(self->ctx)); + return PyLong_FromSize_t(SSL_CTX_get_num_tickets(self->ctx)); } static int @@ -3735,8 +3755,6 @@ get_post_handshake_auth(PySSLContext *self, void *c) { #if TLS1_3_VERSION static int set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) { - int (*verify_cb)(int, X509_STORE_CTX *) = NULL; - int mode = SSL_CTX_get_verify_mode(self->ctx); if (arg == NULL) { PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); return -1; @@ -3748,17 +3766,8 @@ set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) { } self->post_handshake_auth = pha; - /* client-side socket setting, ignored by server-side */ - SSL_CTX_set_post_handshake_auth(self->ctx, pha); - - /* server-side socket setting, ignored by client-side */ - verify_cb = SSL_CTX_get_verify_callback(self->ctx); - if (pha) { - mode |= SSL_VERIFY_POST_HANDSHAKE; - } else { - mode ^= SSL_VERIFY_POST_HANDSHAKE; - } - SSL_CTX_set_verify(self->ctx, mode, verify_cb); + /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for + * server sockets and SSL_set_post_handshake_auth() for client. */ return 0; } @@ -3874,15 +3883,15 @@ _password_callback(char *buf, int size, int rwflag, void *userdata) /*[clinic input] _ssl._SSLContext.load_cert_chain certfile: object - keyfile: object = NULL - password: object = NULL + keyfile: object = None + password: object = None [clinic start generated code]*/ static PyObject * _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, PyObject *keyfile, PyObject *password) -/*[clinic end generated code: output=9480bc1c380e2095 input=7cf9ac673cbee6fc]*/ +/*[clinic end generated code: output=9480bc1c380e2095 input=30bc7e967ea01a58]*/ { PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL; pem_password_cb *orig_passwd_cb = SSL_CTX_get_default_passwd_cb(self->ctx); @@ -3908,7 +3917,7 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, } goto error; } - if (password && password != Py_None) { + if (password != Py_None) { if (PyCallable_Check(password)) { pw_info.callable = password; } else if (!_pwinfo_set(&pw_info, password, @@ -4066,9 +4075,9 @@ _add_ca_certs(PySSLContext *self, void *data, Py_ssize_t len, /*[clinic input] _ssl._SSLContext.load_verify_locations - cafile: object = NULL - capath: object = NULL - cadata: object = NULL + cafile: object = None + capath: object = None + cadata: object = None [clinic start generated code]*/ @@ -4077,7 +4086,7 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, PyObject *cafile, PyObject *capath, PyObject *cadata) -/*[clinic end generated code: output=454c7e41230ca551 input=997f1fb3a784ef88]*/ +/*[clinic end generated code: output=454c7e41230ca551 input=42ecfe258233e194]*/ { PyObject *cafile_bytes = NULL, *capath_bytes = NULL; const char *cafile_buf = NULL, *capath_buf = NULL; @@ -5508,7 +5517,7 @@ parseKeyUsage(PCCERT_CONTEXT pCertCtx, DWORD flags) } return PyErr_SetFromWindowsErr(error); } - retval = PySet_New(NULL); + retval = PyFrozenSet_New(NULL); if (retval == NULL) { goto error; } @@ -5572,6 +5581,7 @@ ssl_collect_certificates(const char *store_name) if (result) { ++storesAdded; } + CertCloseStore(hSystemStore, 0); /* flag must be 0 */ } } if (storesAdded == 0) { @@ -5582,20 +5592,6 @@ ssl_collect_certificates(const char *store_name) return hCollectionStore; } -/* code from Objects/listobject.c */ - -static int -list_contains(PyListObject *a, PyObject *el) -{ - Py_ssize_t i; - int cmp; - - for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) - cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i), - Py_EQ); - return cmp; -} - /*[clinic input] _ssl.enum_certificates store_name: str @@ -5618,7 +5614,7 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name) PyObject *keyusage = NULL, *cert = NULL, *enc = NULL, *tup = NULL; PyObject *result = NULL; - result = PyList_New(0); + result = PySet_New(NULL); if (result == NULL) { return NULL; } @@ -5658,11 +5654,10 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name) enc = NULL; PyTuple_SET_ITEM(tup, 2, keyusage); keyusage = NULL; - if (!list_contains((PyListObject*)result, tup)) { - if (PyList_Append(result, tup) < 0) { - Py_CLEAR(result); - break; - } + if (PySet_Add(result, tup) == -1) { + Py_CLEAR(result); + Py_CLEAR(tup); + break; } Py_CLEAR(tup); } @@ -5686,7 +5681,14 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name) return PyErr_SetFromWindowsErr(GetLastError()); } - return result; + /* convert set to list */ + if (result == NULL) { + return NULL; + } else { + PyObject *lst = PySequence_List(result); + Py_DECREF(result); + return lst; + } } /*[clinic input] @@ -5710,7 +5712,7 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name) PyObject *crl = NULL, *enc = NULL, *tup = NULL; PyObject *result = NULL; - result = PyList_New(0); + result = PySet_New(NULL); if (result == NULL) { return NULL; } @@ -5740,11 +5742,10 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name) PyTuple_SET_ITEM(tup, 1, enc); enc = NULL; - if (!list_contains((PyListObject*)result, tup)) { - if (PyList_Append(result, tup) < 0) { - Py_CLEAR(result); - break; - } + if (PySet_Add(result, tup) == -1) { + Py_CLEAR(result); + Py_CLEAR(tup); + break; } Py_CLEAR(tup); } @@ -5766,7 +5767,14 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name) Py_XDECREF(result); return PyErr_SetFromWindowsErr(GetLastError()); } - return result; + /* convert set to list */ + if (result == NULL) { + return NULL; + } else { + PyObject *lst = PySequence_List(result); + Py_DECREF(result); + return lst; + } } #endif /* _MSC_VER */ diff --git a/Modules/_stat.c b/Modules/_stat.c index f6cb303500cd14..6a3020a00d1142 100644 --- a/Modules/_stat.c +++ b/Modules/_stat.c @@ -589,6 +589,13 @@ PyInit__stat(void) if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_SYSTEM)) return NULL; if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_TEMPORARY)) return NULL; if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_VIRTUAL)) return NULL; + + if (PyModule_AddObject(m, "IO_REPARSE_TAG_SYMLINK", + PyLong_FromUnsignedLong(IO_REPARSE_TAG_SYMLINK))) return NULL; + if (PyModule_AddObject(m, "IO_REPARSE_TAG_MOUNT_POINT", + PyLong_FromUnsignedLong(IO_REPARSE_TAG_MOUNT_POINT))) return NULL; + if (PyModule_AddObject(m, "IO_REPARSE_TAG_APPEXECLINK", + PyLong_FromUnsignedLong(IO_REPARSE_TAG_APPEXECLINK))) return NULL; #endif return m; diff --git a/Modules/_statisticsmodule.c b/Modules/_statisticsmodule.c new file mode 100644 index 00000000000000..a646e96d0165c0 --- /dev/null +++ b/Modules/_statisticsmodule.c @@ -0,0 +1,150 @@ +/* statistics accelerator C extension: _statistics module. */ + +#include "Python.h" +#include "structmember.h" +#include "clinic/_statisticsmodule.c.h" + +/*[clinic input] +module _statistics + +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=864a6f59b76123b2]*/ + +/* + * There is no closed-form solution to the inverse CDF for the normal + * distribution, so we use a rational approximation instead: + * Wichura, M.J. (1988). "Algorithm AS241: The Percentage Points of the + * Normal Distribution". Applied Statistics. Blackwell Publishing. 37 + * (3): 477–484. doi:10.2307/2347330. JSTOR 2347330. + */ + +/*[clinic input] +_statistics._normal_dist_inv_cdf -> double + p: double + mu: double + sigma: double + / +[clinic start generated code]*/ + +static double +_statistics__normal_dist_inv_cdf_impl(PyObject *module, double p, double mu, + double sigma) +/*[clinic end generated code: output=02fd19ddaab36602 input=24715a74be15296a]*/ +{ + double q, num, den, r, x; + if (p <= 0.0 || p >= 1.0 || sigma <= 0.0) { + goto error; + } + + q = p - 0.5; + if(fabs(q) <= 0.425) { + r = 0.180625 - q * q; + // Hash sum-55.8831928806149014439 + num = (((((((2.5090809287301226727e+3 * r + + 3.3430575583588128105e+4) * r + + 6.7265770927008700853e+4) * r + + 4.5921953931549871457e+4) * r + + 1.3731693765509461125e+4) * r + + 1.9715909503065514427e+3) * r + + 1.3314166789178437745e+2) * r + + 3.3871328727963666080e+0) * q; + den = (((((((5.2264952788528545610e+3 * r + + 2.8729085735721942674e+4) * r + + 3.9307895800092710610e+4) * r + + 2.1213794301586595867e+4) * r + + 5.3941960214247511077e+3) * r + + 6.8718700749205790830e+2) * r + + 4.2313330701600911252e+1) * r + + 1.0); + if (den == 0.0) { + goto error; + } + x = num / den; + return mu + (x * sigma); + } + r = (q <= 0.0) ? p : (1.0 - p); + if (r <= 0.0 || r >= 1.0) { + goto error; + } + r = sqrt(-log(r)); + if (r <= 5.0) { + r = r - 1.6; + // Hash sum-49.33206503301610289036 + num = (((((((7.74545014278341407640e-4 * r + + 2.27238449892691845833e-2) * r + + 2.41780725177450611770e-1) * r + + 1.27045825245236838258e+0) * r + + 3.64784832476320460504e+0) * r + + 5.76949722146069140550e+0) * r + + 4.63033784615654529590e+0) * r + + 1.42343711074968357734e+0); + den = (((((((1.05075007164441684324e-9 * r + + 5.47593808499534494600e-4) * r + + 1.51986665636164571966e-2) * r + + 1.48103976427480074590e-1) * r + + 6.89767334985100004550e-1) * r + + 1.67638483018380384940e+0) * r + + 2.05319162663775882187e+0) * r + + 1.0); + } else { + r -= 5.0; + // Hash sum-47.52583317549289671629 + num = (((((((2.01033439929228813265e-7 * r + + 2.71155556874348757815e-5) * r + + 1.24266094738807843860e-3) * r + + 2.65321895265761230930e-2) * r + + 2.96560571828504891230e-1) * r + + 1.78482653991729133580e+0) * r + + 5.46378491116411436990e+0) * r + + 6.65790464350110377720e+0); + den = (((((((2.04426310338993978564e-15 * r + + 1.42151175831644588870e-7) * r + + 1.84631831751005468180e-5) * r + + 7.86869131145613259100e-4) * r + + 1.48753612908506148525e-2) * r + + 1.36929880922735805310e-1) * r + + 5.99832206555887937690e-1) * r + + 1.0); + } + if (den == 0.0) { + goto error; + } + x = num / den; + if (q < 0.0) { + x = -x; + } + return mu + (x * sigma); + + error: + PyErr_SetString(PyExc_ValueError, "inv_cdf undefined for these parameters"); + return -1.0; +} + + +static PyMethodDef statistics_methods[] = { + _STATISTICS__NORMAL_DIST_INV_CDF_METHODDEF + {NULL, NULL, 0, NULL} +}; + +PyDoc_STRVAR(statistics_doc, +"Accelerators for the statistics module.\n"); + +static struct PyModuleDef statisticsmodule = { + PyModuleDef_HEAD_INIT, + "_statistics", + statistics_doc, + -1, + statistics_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__statistics(void) +{ + PyObject *m = PyModule_Create(&statisticsmodule); + if (!m) return NULL; + return m; +} diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index f059b4df11b734..46d772cff608e2 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -32,6 +32,8 @@ # error "_testcapi must test the public Python C API, not CPython internal C API" #endif +static struct PyModuleDef _testcapimodule; + static PyObject *TestError; /* set to exception object in init */ /* Raise TestError with test_name + ": " + msg, and return NULL. */ @@ -825,6 +827,26 @@ test_long_as_size_t(PyObject *self, PyObject *Py_UNUSED(ignored)) 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. */ @@ -4469,15 +4491,25 @@ test_pymem_getallocatorsname(PyObject *self, PyObject *args) static PyObject* -pyobject_is_freed(PyObject *self, PyObject *op) +test_pyobject_is_freed(const char *test_name, PyObject *op) { - int res = _PyObject_IsFreed(op); - return PyBool_FromLong(res); + if (!_PyObject_IsFreed(op)) { + return raiseTestError(test_name, "object is not seen as freed"); + } + Py_RETURN_NONE; } static PyObject* -pyobject_uninitialized(PyObject *self, PyObject *args) +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) { @@ -4486,12 +4518,12 @@ pyobject_uninitialized(PyObject *self, PyObject *args) /* Initialize reference count to avoid early crash in ceval or GC */ Py_REFCNT(op) = 1; /* object fields like ob_type are uninitialized! */ - return op; + return test_pyobject_is_freed("check_pyobject_uninitialized_is_freed", op); } static PyObject* -pyobject_forbidden_bytes(PyObject *self, PyObject *args) +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)); @@ -4501,13 +4533,13 @@ pyobject_forbidden_bytes(PyObject *self, PyObject *args) /* Initialize reference count to avoid early crash in ceval or GC */ Py_REFCNT(op) = 1; /* ob_type field is after the memory block: part of "forbidden bytes" - when using debug hooks on memory allocatrs! */ - return op; + when using debug hooks on memory allocators! */ + return test_pyobject_is_freed("check_pyobject_forbidden_bytes_is_freed", op); } static PyObject* -pyobject_freed(PyObject *self, PyObject *args) +check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) { PyObject *op = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type); if (op == NULL) { @@ -4517,7 +4549,7 @@ pyobject_freed(PyObject *self, PyObject *args) /* Reset reference count to avoid early crash in ceval or GC */ Py_REFCNT(op) = 1; /* object memory is freed! */ - return op; + return test_pyobject_is_freed("check_pyobject_freed_is_freed", op); } @@ -5070,6 +5102,8 @@ static PyMethodDef TestMethods[] = { {"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}, @@ -5242,10 +5276,10 @@ static PyMethodDef TestMethods[] = { {"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}, - {"pyobject_is_freed", (PyCFunction)(void(*)(void))pyobject_is_freed, METH_O}, - {"pyobject_uninitialized", pyobject_uninitialized, METH_NOARGS}, - {"pyobject_forbidden_bytes", pyobject_forbidden_bytes, METH_NOARGS}, - {"pyobject_freed", pyobject_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}, + {"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}, @@ -5932,6 +5966,198 @@ static PyTypeObject MethodDescriptor2_Type = { .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | _Py_TPFLAGS_HAVE_VECTORCALL, }; +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 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_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_Del(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(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 +}; + static struct PyModuleDef _testcapimodule = { PyModuleDef_HEAD_INIT, @@ -5985,6 +6211,10 @@ PyInit__testcapi(void) Py_INCREF(&MyList_Type); PyModule_AddObject(m, "MyList", (PyObject *)&MyList_Type); + /* bpo-37250: old Cython code sets tp_print to 0, we check that + * this doesn't break anything. */ + MyList_Type.tp_print = 0; + if (PyType_Ready(&MethodDescriptorBase_Type) < 0) return NULL; Py_INCREF(&MethodDescriptorBase_Type); @@ -6062,5 +6292,40 @@ PyInit__testcapi(void) TestError = PyErr_NewException("_testcapi.error", NULL, NULL); Py_INCREF(TestError); PyModule_AddObject(m, "error", TestError); + + 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 *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); + + PyState_AddModule(m, &_testcapimodule); return m; } diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index d5e40ef999e3d5..fadf57aaa762e1 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1305,6 +1305,7 @@ 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; @@ -1312,7 +1313,9 @@ thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value, PyObject *name = NULL; if (thread != Py_None) { - name = PyObject_GetAttrString(thread, "name"); + if (_PyObject_LookupAttrId(thread, &PyId_name, &name) < 0) { + return -1; + } } if (name != NULL) { if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) { @@ -1322,8 +1325,6 @@ thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value, Py_DECREF(name); } else { - PyErr_Clear(); - unsigned long ident = PyThread_get_thread_ident(); PyObject *str = PyUnicode_FromFormat("%lu", ident); if (str != NULL) { diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 613a95b0897255..b622c158a48fac 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -96,6 +96,24 @@ Copyright (C) 1994 Steen Lumholt. #endif /* HAVE_CREATEFILEHANDLER */ +/* Use OS native encoding for converting between Python strings and + Tcl objects. + On Windows use UTF-16 (or UTF-32 for 32-bit Tcl_UniChar) with the + "surrogatepass" error handler for converting to/from Tcl Unicode objects. + On Linux use UTF-8 with the "surrogateescape" error handler for converting + to/from Tcl String objects. */ +#ifdef MS_WINDOWS +#define USE_TCL_UNICODE 1 +#else +#define USE_TCL_UNICODE 0 +#endif + +#if PY_LITTLE_ENDIAN +#define NATIVE_BYTEORDER -1 +#else +#define NATIVE_BYTEORDER 1 +#endif + #ifdef MS_WINDOWS #include #define WAIT_FOR_STDIN @@ -290,7 +308,6 @@ typedef struct { } TkappObject; #define Tkapp_Interp(v) (((TkappObject *) (v))->interp) -#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v)) #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \ (void *) v, Py_REFCNT(v))) @@ -311,10 +328,16 @@ static int tk_load_failed = 0; #endif +static PyObject *Tkapp_UnicodeResult(TkappObject *); + static PyObject * -Tkinter_Error(PyObject *v) +Tkinter_Error(TkappObject *self) { - PyErr_SetString(Tkinter_TclError, Tkapp_Result(v)); + PyObject *res = Tkapp_UnicodeResult(self); + if (res != NULL) { + PyErr_SetObject(Tkinter_TclError, res); + Py_DECREF(res); + } return NULL; } @@ -368,30 +391,35 @@ static PyObject * unicodeFromTclStringAndSize(const char *s, Py_ssize_t size) { PyObject *r = PyUnicode_DecodeUTF8(s, size, NULL); - if (!r && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { - /* Tcl encodes null character as \xc0\x80 */ - if (memchr(s, '\xc0', size)) { - char *buf, *q; - const char *e = s + size; - PyErr_Clear(); - q = buf = (char *)PyMem_Malloc(size); - if (buf == NULL) { - PyErr_NoMemory(); - return NULL; - } - while (s != e) { - if (s + 1 != e && s[0] == '\xc0' && s[1] == '\x80') { - *q++ = '\0'; - s += 2; - } - else - *q++ = *s++; + if (r != NULL || !PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { + return r; + } + + char *buf = NULL; + PyErr_Clear(); + /* Tcl encodes null character as \xc0\x80 */ + if (memchr(s, '\xc0', size)) { + char *q; + const char *e = s + size; + q = buf = (char *)PyMem_Malloc(size); + if (buf == NULL) { + PyErr_NoMemory(); + return NULL; + } + while (s != e) { + if (s + 1 != e && s[0] == '\xc0' && s[1] == '\x80') { + *q++ = '\0'; + s += 2; } - s = buf; - size = q - s; - r = PyUnicode_DecodeUTF8(s, size, NULL); - PyMem_Free(buf); + else + *q++ = *s++; } + s = buf; + size = q - s; + } + r = PyUnicode_DecodeUTF8(s, size, "surrogateescape"); + if (buf != NULL) { + PyMem_Free(buf); } return r; } @@ -406,8 +434,21 @@ static PyObject * unicodeFromTclObj(Tcl_Obj *value) { int len; - char *s = Tcl_GetStringFromObj(value, &len); +#if USE_TCL_UNICODE + int byteorder = NATIVE_BYTEORDER; + const Tcl_UniChar *u = Tcl_GetUnicodeFromObj(value, &len); + if (sizeof(Tcl_UniChar) == 2) + return PyUnicode_DecodeUTF16((const char *)u, len * 2, + "surrogatepass", &byteorder); + else if (sizeof(Tcl_UniChar) == 4) + return PyUnicode_DecodeUTF32((const char *)u, len * 4, + "surrogatepass", &byteorder); + else + Py_UNREACHABLE(); +#else + const char *s = Tcl_GetStringFromObj(value, &len); return unicodeFromTclStringAndSize(s, len); +#endif } @@ -746,7 +787,7 @@ Tkapp_New(const char *screenName, const char *className, #endif if (Tcl_AppInit(v->interp) != TCL_OK) { - PyObject *result = Tkinter_Error((PyObject *)v); + PyObject *result = Tkinter_Error(v); #ifdef TKINTER_PROTECT_LOADTK if (wantTk) { const char *_tkinter_tk_failed; @@ -817,12 +858,6 @@ PyTclObject_dealloc(PyTclObject *self) Py_DECREF(tp); } -static const char * -PyTclObject_TclString(PyObject *self) -{ - return Tcl_GetString(((PyTclObject*)self)->value); -} - /* Like _str, but create Unicode if necessary. */ PyDoc_STRVAR(PyTclObject_string__doc__, "the string representation of this object, either as str or bytes"); @@ -1048,53 +1083,51 @@ AsObj(PyObject *value) } if (PyUnicode_Check(value)) { - void *inbuf; - Py_ssize_t size; - int kind; - Tcl_UniChar *outbuf = NULL; - Py_ssize_t i; - size_t allocsize; - if (PyUnicode_READY(value) == -1) return NULL; - inbuf = PyUnicode_DATA(value); - size = PyUnicode_GET_LENGTH(value); - if (size == 0) - return Tcl_NewUnicodeObj((const void *)"", 0); + Py_ssize_t size = PyUnicode_GET_LENGTH(value); + if (size == 0) { + return Tcl_NewStringObj("", 0); + } if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) { PyErr_SetString(PyExc_OverflowError, "string is too long"); return NULL; } - kind = PyUnicode_KIND(value); - if (kind == sizeof(Tcl_UniChar)) - return Tcl_NewUnicodeObj(inbuf, (int)size); - allocsize = ((size_t)size) * sizeof(Tcl_UniChar); - outbuf = (Tcl_UniChar*)PyMem_Malloc(allocsize); - /* Else overflow occurred, and we take the next exit */ - if (!outbuf) { - PyErr_NoMemory(); - return NULL; + if (PyUnicode_IS_ASCII(value)) { + return Tcl_NewStringObj((const char *)PyUnicode_DATA(value), + (int)size); } - for (i = 0; i < size; i++) { - Py_UCS4 ch = PyUnicode_READ(kind, inbuf, i); - /* We cannot test for sizeof(Tcl_UniChar) directly, - so we test for UTF-8 size instead. */ -#if TCL_UTF_MAX == 3 - if (ch >= 0x10000) { - /* Tcl doesn't do UTF-16, yet. */ - PyErr_Format(Tkinter_TclError, - "character U+%x is above the range " - "(U+0000-U+FFFF) allowed by Tcl", - ch); - PyMem_Free(outbuf); - return NULL; - } + + PyObject *encoded; +#if USE_TCL_UNICODE + if (sizeof(Tcl_UniChar) == 2) + encoded = _PyUnicode_EncodeUTF16(value, + "surrogatepass", NATIVE_BYTEORDER); + else if (sizeof(Tcl_UniChar) == 4) + encoded = _PyUnicode_EncodeUTF32(value, + "surrogatepass", NATIVE_BYTEORDER); + else + Py_UNREACHABLE(); +#else + encoded = _PyUnicode_AsUTF8String(value, "surrogateescape"); #endif - outbuf[i] = ch; + if (!encoded) { + return NULL; } - result = Tcl_NewUnicodeObj(outbuf, (int)size); - PyMem_Free(outbuf); + size = PyBytes_GET_SIZE(encoded); + if (size > INT_MAX) { + Py_DECREF(encoded); + PyErr_SetString(PyExc_OverflowError, "string is too long"); + return NULL; + } +#if USE_TCL_UNICODE + result = Tcl_NewUnicodeObj((const Tcl_UniChar *)PyBytes_AS_STRING(encoded), + (int)(size / sizeof(Tcl_UniChar))); +#else + result = Tcl_NewStringObj(PyBytes_AS_STRING(encoded), (int)size); +#endif + Py_DECREF(encoded); return result; } @@ -1113,7 +1146,7 @@ AsObj(PyObject *value) } static PyObject * -fromBoolean(PyObject* tkapp, Tcl_Obj *value) +fromBoolean(TkappObject *tkapp, Tcl_Obj *value) { int boolValue; if (Tcl_GetBooleanFromObj(Tkapp_Interp(tkapp), value, &boolValue) == TCL_ERROR) @@ -1122,7 +1155,7 @@ fromBoolean(PyObject* tkapp, Tcl_Obj *value) } static PyObject* -fromWideIntObj(PyObject* tkapp, Tcl_Obj *value) +fromWideIntObj(TkappObject *tkapp, Tcl_Obj *value) { Tcl_WideInt wideValue; if (Tcl_GetWideIntFromObj(Tkapp_Interp(tkapp), value, &wideValue) == TCL_OK) { @@ -1138,7 +1171,7 @@ fromWideIntObj(PyObject* tkapp, Tcl_Obj *value) #ifdef HAVE_LIBTOMMAMTH static PyObject* -fromBignumObj(PyObject* tkapp, Tcl_Obj *value) +fromBignumObj(TkappObject *tkapp, Tcl_Obj *value) { mp_int bigValue; unsigned long numBytes; @@ -1174,32 +1207,31 @@ fromBignumObj(PyObject* tkapp, Tcl_Obj *value) #endif static PyObject* -FromObj(PyObject* tkapp, Tcl_Obj *value) +FromObj(TkappObject *tkapp, Tcl_Obj *value) { PyObject *result = NULL; - TkappObject *app = (TkappObject*)tkapp; Tcl_Interp *interp = Tkapp_Interp(tkapp); if (value->typePtr == NULL) { - return unicodeFromTclStringAndSize(value->bytes, value->length); + return unicodeFromTclObj(value); } - if (value->typePtr == app->BooleanType || - value->typePtr == app->OldBooleanType) { + if (value->typePtr == tkapp->BooleanType || + value->typePtr == tkapp->OldBooleanType) { return fromBoolean(tkapp, value); } - if (value->typePtr == app->ByteArrayType) { + if (value->typePtr == tkapp->ByteArrayType) { int size; char *data = (char*)Tcl_GetByteArrayFromObj(value, &size); return PyBytes_FromStringAndSize(data, size); } - if (value->typePtr == app->DoubleType) { + if (value->typePtr == tkapp->DoubleType) { return PyFloat_FromDouble(value->internalRep.doubleValue); } - if (value->typePtr == app->IntType) { + if (value->typePtr == tkapp->IntType) { long longValue; if (Tcl_GetLongFromObj(interp, value, &longValue) == TCL_OK) return PyLong_FromLong(longValue); @@ -1207,8 +1239,8 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) fall through to wideInt handling. */ } - if (value->typePtr == app->IntType || - value->typePtr == app->WideIntType) { + if (value->typePtr == tkapp->IntType || + value->typePtr == tkapp->WideIntType) { result = fromWideIntObj(tkapp, value); if (result != NULL || PyErr_Occurred()) return result; @@ -1218,14 +1250,14 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) } #ifdef HAVE_LIBTOMMAMTH - if (value->typePtr == app->IntType || - value->typePtr == app->WideIntType || - value->typePtr == app->BignumType) { + if (value->typePtr == tkapp->IntType || + value->typePtr == tkapp->WideIntType || + value->typePtr == tkapp->BignumType) { return fromBignumObj(tkapp, value); } #endif - if (value->typePtr == app->ListType) { + if (value->typePtr == tkapp->ListType) { int size; int i, status; PyObject *elem; @@ -1253,30 +1285,28 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) return result; } - if (value->typePtr == app->ProcBodyType) { + if (value->typePtr == tkapp->ProcBodyType) { /* fall through: return tcl object. */ } - if (value->typePtr == app->StringType) { - return PyUnicode_FromKindAndData( - sizeof(Tcl_UniChar), Tcl_GetUnicode(value), - Tcl_GetCharLength(value)); + if (value->typePtr == tkapp->StringType) { + return unicodeFromTclObj(value); } #if TK_HEX_VERSION >= 0x08050000 - if (app->BooleanType == NULL && + if (tkapp->BooleanType == NULL && strcmp(value->typePtr->name, "booleanString") == 0) { /* booleanString type is not registered in Tcl */ - app->BooleanType = value->typePtr; + tkapp->BooleanType = value->typePtr; return fromBoolean(tkapp, value); } #endif #ifdef HAVE_LIBTOMMAMTH - if (app->BignumType == NULL && + if (tkapp->BignumType == NULL && strcmp(value->typePtr->name, "bignum") == 0) { /* bignum type is not registered in Tcl */ - app->BignumType = value->typePtr; + tkapp->BignumType = value->typePtr; return fromBignumObj(tkapp, value); } #endif @@ -1366,19 +1396,28 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) return NULL; } +/* Convert the results of a command call into a Python string. */ + +static PyObject * +Tkapp_UnicodeResult(TkappObject *self) +{ + return unicodeFromTclObj(Tcl_GetObjResult(self->interp)); +} + + /* Convert the results of a command call into a Python objects. */ -static PyObject* -Tkapp_CallResult(TkappObject *self) +static PyObject * +Tkapp_ObjectResult(TkappObject *self) { PyObject *res = NULL; Tcl_Obj *value = Tcl_GetObjResult(self->interp); - if(self->wantobjects) { + if (self->wantobjects) { /* Not sure whether the IncrRef is necessary, but something may overwrite the interpreter result while we are converting it. */ Tcl_IncrRefCount(value); - res = FromObj((PyObject*)self, value); + res = FromObj(self, value); Tcl_DecrRefCount(value); } else { res = unicodeFromTclObj(value); @@ -1410,15 +1449,13 @@ Tkapp_CallProc(Tkapp_CallEvent *e, int flags) i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags); ENTER_PYTHON if (i == TCL_ERROR) { - *(e->res) = NULL; - *(e->exc_type) = NULL; - *(e->exc_tb) = NULL; - *(e->exc_value) = PyObject_CallFunction( - Tkinter_TclError, "s", - Tcl_GetStringResult(e->self->interp)); + *(e->res) = Tkinter_Error(e->self); } else { - *(e->res) = Tkapp_CallResult(e->self); + *(e->res) = Tkapp_ObjectResult(e->self); + } + if (*(e->res) == NULL) { + PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb); } LEAVE_PYTHON @@ -1506,9 +1543,9 @@ Tkapp_Call(PyObject *selfptr, PyObject *args) ENTER_OVERLAP if (i == TCL_ERROR) - Tkinter_Error(selfptr); + Tkinter_Error(self); else - res = Tkapp_CallResult(self); + res = Tkapp_ObjectResult(self); LEAVE_OVERLAP_TCL @@ -1540,9 +1577,9 @@ _tkinter_tkapp_eval_impl(TkappObject *self, const char *script) err = Tcl_Eval(Tkapp_Interp(self), script); ENTER_OVERLAP if (err == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else - res = unicodeFromTclString(Tkapp_Result(self)); + res = Tkapp_UnicodeResult(self); LEAVE_OVERLAP_TCL return res; } @@ -1569,9 +1606,9 @@ _tkinter_tkapp_evalfile_impl(TkappObject *self, const char *fileName) err = Tcl_EvalFile(Tkapp_Interp(self), fileName); ENTER_OVERLAP if (err == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else - res = unicodeFromTclString(Tkapp_Result(self)); + res = Tkapp_UnicodeResult(self); LEAVE_OVERLAP_TCL return res; } @@ -1598,9 +1635,9 @@ _tkinter_tkapp_record_impl(TkappObject *self, const char *script) err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL); ENTER_OVERLAP if (err == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else - res = unicodeFromTclString(Tkapp_Result(self)); + res = Tkapp_UnicodeResult(self); LEAVE_OVERLAP_TCL return res; } @@ -1631,13 +1668,13 @@ _tkinter_tkapp_adderrorinfo_impl(TkappObject *self, const char *msg) /** Tcl Variable **/ -typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags); +typedef PyObject* (*EventFunc)(TkappObject *, PyObject *, int); TCL_DECLARE_MUTEX(var_mutex) typedef struct VarEvent { Tcl_Event ev; /* must be first */ - PyObject *self; + TkappObject *self; PyObject *args; int flags; EventFunc func; @@ -1692,7 +1729,7 @@ varname_converter(PyObject *in, void *_out) return 1; } if (PyTclObject_Check(in)) { - *out = PyTclObject_TclString(in); + *out = Tcl_GetString(((PyTclObject *)in)->value); return 1; } PyErr_Format(PyExc_TypeError, @@ -1750,7 +1787,7 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) PyErr_NoMemory(); return NULL; } - ev->self = selfptr; + ev->self = self; ev->args = args; ev->flags = flags; ev->func = func; @@ -1770,11 +1807,11 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) return res; } /* Tcl is not threaded, or this is the interpreter thread. */ - return func(selfptr, args, flags); + return func(self, args, flags); } static PyObject * -SetVar(PyObject *self, PyObject *args, int flags) +SetVar(TkappObject *self, PyObject *args, int flags) { const char *name1, *name2; PyObject *newValue; @@ -1843,7 +1880,7 @@ Tkapp_GlobalSetVar(PyObject *self, PyObject *args) static PyObject * -GetVar(PyObject *self, PyObject *args, int flags) +GetVar(TkappObject *self, PyObject *args, int flags) { const char *name1, *name2=NULL; PyObject *res = NULL; @@ -1858,10 +1895,9 @@ GetVar(PyObject *self, PyObject *args, int flags) tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags); ENTER_OVERLAP if (tres == NULL) { - PyErr_SetString(Tkinter_TclError, - Tcl_GetStringResult(Tkapp_Interp(self))); + Tkinter_Error(self); } else { - if (((TkappObject*)self)->wantobjects) { + if (self->wantobjects) { res = FromObj(self, tres); } else { @@ -1887,7 +1923,7 @@ Tkapp_GlobalGetVar(PyObject *self, PyObject *args) static PyObject * -UnsetVar(PyObject *self, PyObject *args, int flags) +UnsetVar(TkappObject *self, PyObject *args, int flags) { char *name1, *name2=NULL; int code; @@ -1959,7 +1995,7 @@ _tkinter_tkapp_getint(TkappObject *self, PyObject *arg) CHECK_STRING_LENGTH(s); value = Tcl_NewStringObj(s, -1); if (value == NULL) - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); } /* Don't use Tcl_GetInt() because it returns ambiguous result for value in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform). @@ -1968,14 +2004,14 @@ _tkinter_tkapp_getint(TkappObject *self, PyObject *arg) value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform). */ #ifdef HAVE_LIBTOMMAMTH - result = fromBignumObj((PyObject *)self, value); + result = fromBignumObj(self, value); #else - result = fromWideIntObj((PyObject *)self, value); + result = fromWideIntObj(self, value); #endif Tcl_DecrRefCount(value); if (result != NULL || PyErr_Occurred()) return result; - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); } /*[clinic input] @@ -2006,7 +2042,7 @@ _tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg) if (Tcl_GetDoubleFromObj(Tkapp_Interp(self), ((PyTclObject*)arg)->value, &v) == TCL_ERROR) - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); return PyFloat_FromDouble(v); } @@ -2014,7 +2050,7 @@ _tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg) return NULL; CHECK_STRING_LENGTH(s); if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR) - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); return PyFloat_FromDouble(v); } @@ -2041,7 +2077,7 @@ _tkinter_tkapp_getboolean(TkappObject *self, PyObject *arg) if (Tcl_GetBooleanFromObj(Tkapp_Interp(self), ((PyTclObject*)arg)->value, &v) == TCL_ERROR) - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); return PyBool_FromLong(v); } @@ -2049,7 +2085,7 @@ _tkinter_tkapp_getboolean(TkappObject *self, PyObject *arg) return NULL; CHECK_STRING_LENGTH(s); if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR) - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); return PyBool_FromLong(v); } @@ -2075,9 +2111,9 @@ _tkinter_tkapp_exprstring_impl(TkappObject *self, const char *s) retval = Tcl_ExprString(Tkapp_Interp(self), s); ENTER_OVERLAP if (retval == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else - res = unicodeFromTclString(Tkapp_Result(self)); + res = Tkapp_UnicodeResult(self); LEAVE_OVERLAP_TCL return res; } @@ -2105,7 +2141,7 @@ _tkinter_tkapp_exprlong_impl(TkappObject *self, const char *s) retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v); ENTER_OVERLAP if (retval == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else res = PyLong_FromLong(v); LEAVE_OVERLAP_TCL @@ -2136,7 +2172,7 @@ _tkinter_tkapp_exprdouble_impl(TkappObject *self, const char *s) ENTER_OVERLAP PyFPE_END_PROTECT(retval) if (retval == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else res = PyFloat_FromDouble(v); LEAVE_OVERLAP_TCL @@ -2165,7 +2201,7 @@ _tkinter_tkapp_exprboolean_impl(TkappObject *self, const char *s) retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v); ENTER_OVERLAP if (retval == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else res = PyLong_FromLong(v); LEAVE_OVERLAP_TCL @@ -2198,12 +2234,12 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) if (Tcl_ListObjGetElements(Tkapp_Interp(self), ((PyTclObject*)arg)->value, &objc, &objv) == TCL_ERROR) { - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); } if (!(v = PyTuple_New(objc))) return NULL; for (i = 0; i < objc; i++) { - PyObject *s = FromObj((PyObject*)self, objv[i]); + PyObject *s = FromObj(self, objv[i]); if (!s) { Py_DECREF(v); return NULL; @@ -2231,7 +2267,7 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR) { PyMem_Free(list); - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); } if (!(v = PyTuple_New(argc))) @@ -2275,16 +2311,16 @@ _tkinter_tkapp_split(TkappObject *self, PyObject *arg) int i; if (Tcl_ListObjGetElements(Tkapp_Interp(self), value, &objc, &objv) == TCL_ERROR) { - return FromObj((PyObject*)self, value); + return FromObj(self, value); } if (objc == 0) return PyUnicode_FromString(""); if (objc == 1) - return FromObj((PyObject*)self, objv[0]); + return FromObj(self, objv[0]); if (!(v = PyTuple_New(objc))) return NULL; for (i = 0; i < objc; i++) { - PyObject *s = FromObj((PyObject*)self, objv[i]); + PyObject *s = FromObj(self, objv[i]); if (!s) { Py_DECREF(v); return NULL; @@ -2331,34 +2367,31 @@ PythonCmd_Error(Tcl_Interp *interp) * function or method. */ static int -PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) +PythonCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) { PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; - PyObject *func, *arg, *res; - int i, rv; + PyObject *args, *res; + int i; Tcl_Obj *obj_res; ENTER_PYTHON - /* TBD: no error checking here since we know, via the - * Tkapp_CreateCommand() that the client data is a two-tuple - */ - func = data->func; - - /* Create argument list (argv1, ..., argvN) */ - if (!(arg = PyTuple_New(argc - 1))) + /* Create argument tuple (objv1, ..., objvN) */ + if (!(args = PyTuple_New(objc - 1))) return PythonCmd_Error(interp); - for (i = 0; i < (argc - 1); i++) { - PyObject *s = unicodeFromTclString(argv[i + 1]); + for (i = 0; i < (objc - 1); i++) { + PyObject *s = unicodeFromTclObj(objv[i + 1]); if (!s) { - Py_DECREF(arg); + Py_DECREF(args); return PythonCmd_Error(interp); } - PyTuple_SET_ITEM(arg, i, s); + PyTuple_SET_ITEM(args, i, s); } - res = PyObject_Call(func, arg, NULL); - Py_DECREF(arg); + + res = PyObject_Call(data->func, args, NULL); + Py_DECREF(args); if (res == NULL) return PythonCmd_Error(interp); @@ -2368,18 +2401,15 @@ PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[ Py_DECREF(res); return PythonCmd_Error(interp); } - else { - Tcl_SetObjResult(interp, obj_res); - rv = TCL_OK; - } - + Tcl_SetObjResult(interp, obj_res); Py_DECREF(res); LEAVE_PYTHON - return rv; + return TCL_OK; } + static void PythonCmdDelete(ClientData clientData) { @@ -2411,7 +2441,7 @@ static int Tkapp_CommandProc(CommandEvent *ev, int flags) { if (ev->create) - *ev->status = Tcl_CreateCommand( + *ev->status = Tcl_CreateObjCommand( ev->interp, ev->name, PythonCmd, ev->data, PythonCmdDelete) == NULL; else @@ -2477,7 +2507,7 @@ _tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name, else { ENTER_TCL - err = Tcl_CreateCommand( + err = Tcl_CreateObjCommand( Tkapp_Interp(self), name, PythonCmd, (ClientData)data, PythonCmdDelete) == NULL; LEAVE_TCL @@ -2953,9 +2983,9 @@ _tkinter_tkapp_loadtk_impl(TkappObject *self) if (err == TCL_ERROR) { /* This sets an exception, but we cannot return right away because we need to exit the overlap first. */ - Tkinter_Error((PyObject *)self); + Tkinter_Error(self); } else { - _tk_exists = Tkapp_Result(self); + _tk_exists = Tcl_GetStringResult(Tkapp_Interp(self)); } LEAVE_OVERLAP_TCL if (err == TCL_ERROR) { @@ -2963,8 +2993,7 @@ _tkinter_tkapp_loadtk_impl(TkappObject *self) } if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) { if (Tk_Init(interp) == TCL_ERROR) { - PyErr_SetString(Tkinter_TclError, - Tcl_GetStringResult(Tkapp_Interp(self))); + Tkinter_Error(self); #ifdef TKINTER_PROTECT_LOADTK tk_load_failed = 1; #endif @@ -3121,8 +3150,8 @@ _tkinter__flatten(PyObject *module, PyObject *item) /*[clinic input] _tkinter.create - screenName: str(accept={str, NoneType}) = NULL - baseName: str = NULL + screenName: str(accept={str, NoneType}) = None + baseName: str = "" className: str = "Tk" interactive: bool(accept={int}) = False wantobjects: bool(accept={int}) = False @@ -3130,7 +3159,7 @@ _tkinter.create if false, then Tk_Init() doesn't get called sync: bool(accept={int}) = False if true, then pass -sync to wish - use: str(accept={str, NoneType}) = NULL + use: str(accept={str, NoneType}) = None if not None, then pass -use to wish / @@ -3141,7 +3170,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=431907c134c80085]*/ +/*[clinic end generated code: output=e3315607648e6bb4 input=da9b17ee7358d862]*/ { /* XXX baseName is not used anymore; * try getting rid of it. */ diff --git a/Modules/_uuidmodule.c b/Modules/_uuidmodule.c index 0b7f2a2545d4eb..0b7aa72e91a1c9 100644 --- a/Modules/_uuidmodule.c +++ b/Modules/_uuidmodule.c @@ -1,14 +1,17 @@ +/* + * Python UUID module that wraps libuuid - + * DCE compatible Universally Unique Identifier library. + */ + #define PY_SSIZE_T_CLEAN #include "Python.h" #ifdef HAVE_UUID_UUID_H #include -#endif -#ifdef HAVE_UUID_H +#elif defined(HAVE_UUID_H) #include #endif - static PyObject * py_uuid_generate_time_safe(PyObject *Py_UNUSED(context), PyObject *Py_UNUSED(ignored)) diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 19d98fd9693446..7842947e54ac56 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -1405,6 +1405,34 @@ typedef struct channelid { _channels *channels; } channelid; +static int +channel_id_converter(PyObject *arg, void *ptr) +{ + int64_t cid; + if (PyObject_TypeCheck(arg, &ChannelIDtype)) { + cid = ((channelid *)arg)->id; + } + else if (PyIndex_Check(arg)) { + cid = PyLong_AsLongLong(arg); + if (cid == -1 && PyErr_Occurred()) { + return 0; + } + if (cid < 0) { + PyErr_Format(PyExc_ValueError, + "channel ID must be a non-negative int, got %R", arg); + return 0; + } + } + else { + PyErr_Format(PyExc_TypeError, + "channel ID must be an int, got %.100s", + arg->ob_type->tp_name); + return 0; + } + *(int64_t *)ptr = cid; + return 1; +} + static channelid * newchannelid(PyTypeObject *cls, int64_t cid, int end, _channels *channels, int force, int resolve) @@ -1437,28 +1465,16 @@ static PyObject * channelid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"id", "send", "recv", "force", "_resolve", NULL}; - PyObject *id; + int64_t cid; int send = -1; int recv = -1; int force = 0; int resolve = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O|$pppp:ChannelID.__new__", kwlist, - &id, &send, &recv, &force, &resolve)) + "O&|$pppp:ChannelID.__new__", kwlist, + channel_id_converter, &cid, &send, &recv, &force, &resolve)) return NULL; - // Coerce and check the ID. - int64_t cid; - if (PyObject_TypeCheck(id, &ChannelIDtype)) { - cid = ((channelid *)id)->id; - } - else { - cid = _Py_CoerceID(id); - if (cid < 0) { - return NULL; - } - } - // Handle "send" and "recv". if (send == 0 && recv == 0) { PyErr_SetString(PyExc_ValueError, @@ -1592,30 +1608,28 @@ channelid_richcompare(PyObject *self, PyObject *other, int op) int equal; if (PyObject_TypeCheck(other, &ChannelIDtype)) { channelid *othercid = (channelid *)other; - if (cid->end != othercid->end) { - equal = 0; - } - else { - equal = (cid->id == othercid->id); - } + equal = (cid->end == othercid->end) && (cid->id == othercid->id); } - else { - other = PyNumber_Long(other); - if (other == NULL) { - PyErr_Clear(); - Py_RETURN_NOTIMPLEMENTED; - } - int64_t othercid = PyLong_AsLongLong(other); - Py_DECREF(other); - if (othercid == -1 && PyErr_Occurred() != NULL) { + else if (PyLong_Check(other)) { + /* Fast path */ + int overflow; + long long othercid = PyLong_AsLongLongAndOverflow(other, &overflow); + if (othercid == -1 && PyErr_Occurred()) { return NULL; } - if (othercid < 0) { - equal = 0; - } - else { - equal = (cid->id == othercid); + equal = !overflow && (othercid >= 0) && (cid->id == othercid); + } + else if (PyNumber_Check(other)) { + PyObject *pyid = PyLong_FromLongLong(cid->id); + if (pyid == NULL) { + return NULL; } + PyObject *res = PyObject_RichCompare(pyid, other, op); + Py_DECREF(pyid); + return res; + } + else { + Py_RETURN_NOTIMPLEMENTED; } if ((op == Py_EQ && equal) || (op == Py_NE && !equal)) { @@ -1754,8 +1768,7 @@ static PyTypeObject ChannelIDtype = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ channelid_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -2017,10 +2030,6 @@ interp_destroy(PyObject *self, PyObject *args, PyObject *kwds) "O:destroy", kwlist, &id)) { return NULL; } - if (!PyLong_Check(id)) { - PyErr_SetString(PyExc_TypeError, "ID must be an int"); - return NULL; - } // Look up the interpreter. PyInterpreterState *interp = _PyInterpreterID_LookUp(id); @@ -2145,10 +2154,6 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds) &id, &code, &shared)) { return NULL; } - if (!PyLong_Check(id)) { - PyErr_SetString(PyExc_TypeError, "first arg (ID) must be an int"); - return NULL; - } // Look up the interpreter. PyInterpreterState *interp = _PyInterpreterID_LookUp(id); @@ -2216,10 +2221,6 @@ interp_is_running(PyObject *self, PyObject *args, PyObject *kwds) "O:is_running", kwlist, &id)) { return NULL; } - if (!PyLong_Check(id)) { - PyErr_SetString(PyExc_TypeError, "ID must be an int"); - return NULL; - } PyInterpreterState *interp = _PyInterpreterID_LookUp(id); if (interp == NULL) { @@ -2268,13 +2269,9 @@ static PyObject * channel_destroy(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", NULL}; - PyObject *id; - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O:channel_destroy", kwlist, &id)) { - return NULL; - } - int64_t cid = _Py_CoerceID(id); - if (cid < 0) { + int64_t cid; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:channel_destroy", kwlist, + channel_id_converter, &cid)) { return NULL; } @@ -2331,14 +2328,10 @@ static PyObject * channel_send(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", "obj", NULL}; - PyObject *id; + int64_t cid; PyObject *obj; - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "OO:channel_send", kwlist, &id, &obj)) { - return NULL; - } - int64_t cid = _Py_CoerceID(id); - if (cid < 0) { + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O:channel_send", kwlist, + channel_id_converter, &cid, &obj)) { return NULL; } @@ -2357,13 +2350,9 @@ static PyObject * channel_recv(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", NULL}; - PyObject *id; - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O:channel_recv", kwlist, &id)) { - return NULL; - } - int64_t cid = _Py_CoerceID(id); - if (cid < 0) { + int64_t cid; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:channel_recv", kwlist, + channel_id_converter, &cid)) { return NULL; } @@ -2379,17 +2368,13 @@ static PyObject * channel_close(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", "send", "recv", "force", NULL}; - PyObject *id; + int64_t cid; int send = 0; int recv = 0; int force = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O|$ppp:channel_close", kwlist, - &id, &send, &recv, &force)) { - return NULL; - } - int64_t cid = _Py_CoerceID(id); - if (cid < 0) { + "O&|$ppp:channel_close", kwlist, + channel_id_converter, &cid, &send, &recv, &force)) { return NULL; } @@ -2431,17 +2416,13 @@ channel_release(PyObject *self, PyObject *args, PyObject *kwds) { // Note that only the current interpreter is affected. static char *kwlist[] = {"cid", "send", "recv", "force", NULL}; - PyObject *id; + int64_t cid; int send = 0; int recv = 0; int force = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O|$ppp:channel_release", kwlist, - &id, &send, &recv, &force)) { - return NULL; - } - int64_t cid = _Py_CoerceID(id); - if (cid < 0) { + "O&|$ppp:channel_release", kwlist, + channel_id_converter, &cid, &send, &recv, &force)) { return NULL; } if (send == 0 && recv == 0) { @@ -2538,7 +2519,6 @@ PyInit__xxsubinterpreters(void) } /* Initialize types */ - ChannelIDtype.tp_base = &PyLong_Type; if (PyType_Ready(&ChannelIDtype) != 0) { return NULL; } diff --git a/Modules/_xxtestfuzz/README.rst b/Modules/_xxtestfuzz/README.rst index b48f3c89a42bb6..42bd02a03cbedd 100644 --- a/Modules/_xxtestfuzz/README.rst +++ b/Modules/_xxtestfuzz/README.rst @@ -35,6 +35,16 @@ And invoke it from ``LLVMFuzzerTestOneInput``:: ``LLVMFuzzerTestOneInput`` will run in oss-fuzz, with each test in ``fuzz_tests.txt`` run separately. +Seed data (corpus) for the test can be provided in a subfolder called +``_corpus`` such as ``fuzz_json_loads_corpus``. A wide variety +of good input samples allows the fuzzer to more easily explore a diverse +set of paths and provides a better base to find buggy input from. + +Dictionaries of tokens (see oss-fuzz documentation for more details) can +be placed in the ``dictionaries`` folder with the name of the test. +For example, ``dictionaries/fuzz_json_loads.dict`` contains JSON tokens +to guide the fuzzer. + What makes a good fuzz test --------------------------- diff --git a/Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict b/Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict new file mode 100644 index 00000000000000..ad64917ccc2c08 --- /dev/null +++ b/Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict @@ -0,0 +1,40 @@ +"0" +",0" +":0" +"0:" +"-1.2e+3" + +"true" +"false" +"null" + +"\"\"" +",\"\"" +":\"\"" +"\"\":" + +"{}" +",{}" +":{}" +"{\"\":0}" +"{{}}" + +"[]" +",[]" +":[]" +"[0]" +"[[]]" + +"''" +"\\" +"\\b" +"\\f" +"\\n" +"\\r" +"\\t" +"\\u0000" +"\\x00" +"\\0" +"\\uD800\\uDC00" +"\\uDBFF\\uDFFF" + diff --git a/Modules/_xxtestfuzz/dictionaries/fuzz_sre_compile.dict b/Modules/_xxtestfuzz/dictionaries/fuzz_sre_compile.dict new file mode 100644 index 00000000000000..961306a87901d0 --- /dev/null +++ b/Modules/_xxtestfuzz/dictionaries/fuzz_sre_compile.dict @@ -0,0 +1,219 @@ +"?" +"abc" +"()" +"[]" +"abc|def" +"abc|def|ghi" +"^xxx$" +"ab\\b\\d\\bcd" +"\\w|\\d" +"a*?" +"abc+" +"abc+?" +"xyz?" +"xyz??" +"xyz{0,1}" +"xyz{0,1}?" +"xyz{93}" +"xyz{1,32}" +"xyz{1,32}?" +"xyz{1,}" +"xyz{1,}?" +"a\\fb\\nc\\rd\\te\\vf" +"a\\nb\\bc" +"(?:foo)" +"(?: foo )" +"foo|(bar|baz)|quux" +"foo(?=bar)baz" +"foo(?!bar)baz" +"foo(?<=bar)baz" +"foo(?)" +"(?.)" +"(?.)\\k" diff --git a/Modules/_xxtestfuzz/fuzz_csv_reader_corpus/test.csv b/Modules/_xxtestfuzz/fuzz_csv_reader_corpus/test.csv new file mode 100644 index 00000000000000..8b7887d0f1d242 Binary files /dev/null and b/Modules/_xxtestfuzz/fuzz_csv_reader_corpus/test.csv differ diff --git a/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json new file mode 100644 index 00000000000000..fe51488c7066f6 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json @@ -0,0 +1 @@ +[] diff --git a/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json new file mode 100644 index 00000000000000..0967ef424bce67 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json @@ -0,0 +1 @@ +{} diff --git a/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json new file mode 100644 index 00000000000000..70e26854369282 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json @@ -0,0 +1,58 @@ +[ + "JSON Test Pattern pass1", + {"object with 1 member":["array with 1 element"]}, + {}, + [], + -42, + true, + false, + null, + { + "integer": 1234567890, + "real": -9876.543210, + "e": 0.123456789e-12, + "E": 1.234567890E+34, + "": 23456789012E66, + "zero": 0, + "one": 1, + "space": " ", + "quote": "\"", + "backslash": "\\", + "controls": "\b\f\n\r\t", + "slash": "/ & \/", + "alpha": "abcdefghijklmnopqrstuvwyz", + "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", + "digit": "0123456789", + "0123456789": "digit", + "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", + "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", + "true": true, + "false": false, + "null": null, + "array":[ ], + "object":{ }, + "address": "50 St. James Street", + "url": "http://www.JSON.org/", + "comment": "// /* */": " ", + " s p a c e d " :[1,2 , 3 + +, + +4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], + "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", + "quotes": "" \u0022 %22 0x22 034 "", + "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" +: "A key can be any string" + }, + 0.5 ,98.6 +, +99.44 +, + +1066, +1e1, +0.1e1, +1e-1, +1e00,2e+00,2e-00 +,"rosebud"] \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json new file mode 100644 index 00000000000000..d3c63c7ad845e4 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json new file mode 100644 index 00000000000000..4528d51f1ac615 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json @@ -0,0 +1,6 @@ +{ + "JSON Test Pattern pass3": { + "The outermost value": "must be an object or array.", + "In this test": "It is an object." + } +} diff --git a/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json new file mode 100644 index 00000000000000..ce1e6ecaec72f4 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json @@ -0,0 +1 @@ +[1, 2, 3, "abcd", "xyz"] diff --git a/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/anchor_links b/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/anchor_links new file mode 100644 index 00000000000000..d99247ccadfd18 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/anchor_links @@ -0,0 +1 @@ +XX] diff --git a/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/characters b/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/characters new file mode 100644 index 00000000000000..0c67ee7dfc1b5d --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/characters @@ -0,0 +1 @@ +XX^(Tim|Robert)\s+the\s+(Enchanter|Shrubber)$ diff --git a/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/isbn b/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/isbn new file mode 100644 index 00000000000000..cce8919e7285ce --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/isbn @@ -0,0 +1 @@ +XX/((978[\--– ])?[0-9][0-9\--– ]{10}[\--– ][0-9xX])|((978)?[0-9]{9}[0-9Xx])/ diff --git a/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/phone_number b/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/phone_number new file mode 100644 index 00000000000000..1e2efc51103be0 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/phone_number @@ -0,0 +1 @@ +XX(\+1|1)?[ \-\.]?\(?(?[0-9]{3})\)?[ \-\.]?(?[0-9]{3})[ \-\.]?(?[0-9]{4})[ \.]*(ext|x)?[ \.]*(?[0-9]{0,5}) diff --git a/Modules/_xxtestfuzz/fuzz_tests.txt b/Modules/_xxtestfuzz/fuzz_tests.txt index 2e53bfdc71619c..9d330a668ee88b 100644 --- a/Modules/_xxtestfuzz/fuzz_tests.txt +++ b/Modules/_xxtestfuzz/fuzz_tests.txt @@ -1,3 +1,7 @@ fuzz_builtin_float fuzz_builtin_int fuzz_builtin_unicode +fuzz_json_loads +fuzz_sre_compile +fuzz_sre_match +fuzz_csv_reader diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index b50eb651271043..1821eb2a0f017b 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -28,8 +28,15 @@ static int fuzz_builtin_float(const char* data, size_t size) { return 0; } +#define MAX_INT_TEST_SIZE 0x10000 + /* Fuzz PyLong_FromUnicodeObject as a proxy for int(str). */ static int fuzz_builtin_int(const char* data, size_t size) { + /* Ignore test cases with very long ints to avoid timeouts + int("9" * 1000000) is not a very interesting test caase */ + if (size > MAX_INT_TEST_SIZE) { + return 0; + } /* Pick a random valid base. (When the fuzzed function takes extra parameters, it's somewhat normal to hash the input to generate those parameters. We want to exercise all code paths, so we do so here.) */ @@ -72,6 +79,256 @@ static int fuzz_builtin_unicode(const char* data, size_t size) { return 0; } +#define MAX_JSON_TEST_SIZE 0x10000 + +PyObject* json_loads_method = NULL; +/* Called by LLVMFuzzerTestOneInput for initialization */ +static int init_json_loads() { + /* Import json.loads */ + PyObject* json_module = PyImport_ImportModule("json"); + if (json_module == NULL) { + return 0; + } + json_loads_method = PyObject_GetAttrString(json_module, "loads"); + return json_loads_method != NULL; +} +/* Fuzz json.loads(x) */ +static int fuzz_json_loads(const char* data, size_t size) { + /* Since python supports arbitrarily large ints in JSON, + long inputs can lead to timeouts on boring inputs like + `json.loads("9" * 100000)` */ + if (size > MAX_JSON_TEST_SIZE) { + return 0; + } + PyObject* input_bytes = PyBytes_FromStringAndSize(data, size); + if (input_bytes == NULL) { + return 0; + } + PyObject* parsed = PyObject_CallFunctionObjArgs(json_loads_method, input_bytes, NULL); + if (parsed == NULL) { + /* Ignore ValueError as the fuzzer will more than likely + generate some invalid json and values */ + if (PyErr_ExceptionMatches(PyExc_ValueError) || + /* Ignore RecursionError as the fuzzer generates long sequences of + arrays such as `[[[...` */ + PyErr_ExceptionMatches(PyExc_RecursionError) || + /* Ignore unicode errors, invalid byte sequences are common */ + PyErr_ExceptionMatches(PyExc_UnicodeDecodeError) + ) { + PyErr_Clear(); + } + } + Py_DECREF(input_bytes); + Py_XDECREF(parsed); + return 0; +} + +#define MAX_RE_TEST_SIZE 0x10000 + +PyObject* sre_compile_method = NULL; +PyObject* sre_error_exception = NULL; +int SRE_FLAG_DEBUG = 0; +/* Called by LLVMFuzzerTestOneInput for initialization */ +static int init_sre_compile() { + /* Import sre_compile.compile and sre.error */ + PyObject* sre_compile_module = PyImport_ImportModule("sre_compile"); + if (sre_compile_module == NULL) { + return 0; + } + sre_compile_method = PyObject_GetAttrString(sre_compile_module, "compile"); + if (sre_compile_method == NULL) { + return 0; + } + + PyObject* sre_constants = PyImport_ImportModule("sre_constants"); + if (sre_constants == NULL) { + return 0; + } + sre_error_exception = PyObject_GetAttrString(sre_constants, "error"); + if (sre_error_exception == NULL) { + return 0; + } + PyObject* debug_flag = PyObject_GetAttrString(sre_constants, "SRE_FLAG_DEBUG"); + if (debug_flag == NULL) { + return 0; + } + SRE_FLAG_DEBUG = PyLong_AsLong(debug_flag); + return 1; +} +/* Fuzz _sre.compile(x) */ +static int fuzz_sre_compile(const char* data, size_t size) { + /* Ignore really long regex patterns that will timeout the fuzzer */ + if (size > MAX_RE_TEST_SIZE) { + return 0; + } + /* We treat the first 2 bytes of the input as a number for the flags */ + if (size < 2) { + return 0; + } + uint16_t flags = ((uint16_t*) data)[0]; + /* We remove the SRE_FLAG_DEBUG if present. This is because it + prints to stdout which greatly decreases fuzzing speed */ + flags &= ~SRE_FLAG_DEBUG; + + /* Pull the pattern from the remaining bytes */ + PyObject* pattern_bytes = PyBytes_FromStringAndSize(data + 2, size - 2); + if (pattern_bytes == NULL) { + return 0; + } + PyObject* flags_obj = PyLong_FromUnsignedLong(flags); + if (flags_obj == NULL) { + Py_DECREF(pattern_bytes); + return 0; + } + + /* compiled = _sre.compile(data[2:], data[0:2] */ + PyObject* compiled = PyObject_CallFunctionObjArgs( + sre_compile_method, pattern_bytes, flags_obj, NULL); + /* Ignore ValueError as the fuzzer will more than likely + generate some invalid combination of flags */ + if (compiled == NULL && PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + } + /* Ignore some common errors thrown by sre_parse: + Overflow, Assertion and Index */ + if (compiled == NULL && (PyErr_ExceptionMatches(PyExc_OverflowError) || + PyErr_ExceptionMatches(PyExc_AssertionError) || + PyErr_ExceptionMatches(PyExc_IndexError)) + ) { + PyErr_Clear(); + } + /* Ignore re.error */ + if (compiled == NULL && PyErr_ExceptionMatches(sre_error_exception)) { + PyErr_Clear(); + } + + Py_DECREF(pattern_bytes); + Py_DECREF(flags_obj); + Py_XDECREF(compiled); + return 0; +} + +/* Some random patterns used to test re.match. + Be careful not to add catostraphically slow regexes here, we want to + exercise the matching code without causing timeouts.*/ +static const char* regex_patterns[] = { + ".", "^", "abc", "abc|def", "^xxx$", "\\b", "()", "[a-zA-Z0-9]", + "abc+", "[^A-Z]", "[x]", "(?=)", "a{z}", "a+b", "a*?", "a??", "a+?", + "{}", "a{,}", "{", "}", "^\\(*\\d{3}\\)*( |-)*\\d{3}( |-)*\\d{4}$", + "(?:a*)*", "a{1,2}?" +}; +const size_t NUM_PATTERNS = sizeof(regex_patterns) / sizeof(regex_patterns[0]); +PyObject** compiled_patterns = NULL; +/* Called by LLVMFuzzerTestOneInput for initialization */ +static int init_sre_match() { + PyObject* re_module = PyImport_ImportModule("re"); + if (re_module == NULL) { + return 0; + } + compiled_patterns = (PyObject**) PyMem_RawMalloc( + sizeof(PyObject*) * NUM_PATTERNS); + if (compiled_patterns == NULL) { + PyErr_NoMemory(); + return 0; + } + + /* Precompile all the regex patterns on the first run for faster fuzzing */ + for (size_t i = 0; i < NUM_PATTERNS; i++) { + PyObject* compiled = PyObject_CallMethod( + re_module, "compile", "y", regex_patterns[i]); + /* Bail if any of the patterns fail to compile */ + if (compiled == NULL) { + return 0; + } + compiled_patterns[i] = compiled; + } + return 1; +} +/* Fuzz re.match(x) */ +static int fuzz_sre_match(const char* data, size_t size) { + if (size < 1 || size > MAX_RE_TEST_SIZE) { + return 0; + } + /* Use the first byte as a uint8_t specifying the index of the + regex to use */ + unsigned char idx = (unsigned char) data[0]; + idx = idx % NUM_PATTERNS; + + /* Pull the string to match from the remaining bytes */ + PyObject* to_match = PyBytes_FromStringAndSize(data + 1, size - 1); + if (to_match == NULL) { + return 0; + } + + PyObject* pattern = compiled_patterns[idx]; + PyObject* match_callable = PyObject_GetAttrString(pattern, "match"); + + PyObject* matches = PyObject_CallFunctionObjArgs(match_callable, to_match, NULL); + + Py_XDECREF(matches); + Py_DECREF(match_callable); + Py_DECREF(to_match); + return 0; +} + +#define MAX_CSV_TEST_SIZE 0x10000 +PyObject* csv_module = NULL; +PyObject* csv_error = NULL; +/* Called by LLVMFuzzerTestOneInput for initialization */ +static int init_csv_reader() { + /* Import csv and csv.Error */ + csv_module = PyImport_ImportModule("csv"); + if (csv_module == NULL) { + return 0; + } + csv_error = PyObject_GetAttrString(csv_module, "Error"); + return csv_error != NULL; +} +/* Fuzz csv.reader([x]) */ +static int fuzz_csv_reader(const char* data, size_t size) { + if (size < 1 || size > MAX_CSV_TEST_SIZE) { + return 0; + } + /* Ignore non null-terminated strings since _csv can't handle + embeded nulls */ + if (memchr(data, '\0', size) == NULL) { + return 0; + } + + PyObject* s = PyUnicode_FromString(data); + /* Ignore exceptions until we have a valid string */ + if (s == NULL) { + PyErr_Clear(); + return 0; + } + + /* Split on \n so we can test multiple lines */ + PyObject* lines = PyObject_CallMethod(s, "split", "s", "\n"); + if (lines == NULL) { + Py_DECREF(s); + return 0; + } + + PyObject* reader = PyObject_CallMethod(csv_module, "reader", "N", lines); + if (reader) { + /* Consume all of the reader as an iterator */ + PyObject* parsed_line; + while ((parsed_line = PyIter_Next(reader))) { + Py_DECREF(parsed_line); + } + } + + /* Ignore csv.Error because we're probably going to generate + some bad files (embeded new-lines, unterminated quotes etc) */ + if (PyErr_ExceptionMatches(csv_error)) { + PyErr_Clear(); + } + + Py_XDECREF(reader); + Py_DECREF(s); + return 0; +} + /* Run fuzzer and abort on failure. */ static int _run_fuzz(const uint8_t *data, size_t size, int(*fuzzer)(const char* , size_t)) { int rv = fuzzer((const char*) data, size); @@ -88,6 +345,13 @@ static int _run_fuzz(const uint8_t *data, size_t size, int(*fuzzer)(const char* /* CPython generates a lot of leak warnings for whatever reason. */ int __lsan_is_turned_off(void) { return 1; } + +int LLVMFuzzerInitialize(int *argc, char ***argv) { + wchar_t* wide_program_name = Py_DecodeLocale(*argv[0], NULL); + Py_SetProgramName(wide_program_name); + return 0; +} + /* Fuzz test interface. This returns the bitwise or of all fuzz test's return values. @@ -113,6 +377,50 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { #endif #if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_builtin_unicode) rv |= _run_fuzz(data, size, fuzz_builtin_unicode); +#endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_json_loads) + static int JSON_LOADS_INITIALIZED = 0; + if (!JSON_LOADS_INITIALIZED && !init_json_loads()) { + PyErr_Print(); + abort(); + } else { + JSON_LOADS_INITIALIZED = 1; + } + + rv |= _run_fuzz(data, size, fuzz_json_loads); +#endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_sre_compile) + static int SRE_COMPILE_INITIALIZED = 0; + if (!SRE_COMPILE_INITIALIZED && !init_sre_compile()) { + PyErr_Print(); + abort(); + } else { + SRE_COMPILE_INITIALIZED = 1; + } + + rv |= _run_fuzz(data, size, fuzz_sre_compile); +#endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_sre_match) + static int SRE_MATCH_INITIALIZED = 0; + if (!SRE_MATCH_INITIALIZED && !init_sre_match()) { + PyErr_Print(); + abort(); + } else { + SRE_MATCH_INITIALIZED = 1; + } + + rv |= _run_fuzz(data, size, fuzz_sre_match); +#endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_csv_reader) + static int CSV_READER_INITIALIZED = 0; + if (!CSV_READER_INITIALIZED && !init_csv_reader()) { + PyErr_Print(); + abort(); + } else { + CSV_READER_INITIALIZED = 1; + } + + rv |= _run_fuzz(data, size, fuzz_csv_reader); #endif return rv; } diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h index 84774f007600f1..5ddbbe221b98b9 100644 --- a/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -55,7 +55,7 @@ _multibytecodec_MultibyteCodec_encode(MultibyteCodecObject *self, PyObject *cons } } else { - _PyArg_BadArgument("encode", 2, "str or None", args[1]); + _PyArg_BadArgument("encode", "argument 'errors'", "str or None", args[1]); goto exit; } skip_optional_pos: @@ -103,7 +103,7 @@ _multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *cons goto exit; } if (!PyBuffer_IsContiguous(&input, 'C')) { - _PyArg_BadArgument("decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("decode", "argument 'input'", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -124,7 +124,7 @@ _multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *cons } } else { - _PyArg_BadArgument("decode", 2, "str or None", args[1]); + _PyArg_BadArgument("decode", "argument 'errors'", "str or None", args[1]); goto exit; } skip_optional_pos: @@ -223,7 +223,7 @@ _multibytecodec_MultibyteIncrementalEncoder_setstate(MultibyteIncrementalEncoder PyLongObject *statelong; if (!PyLong_Check(arg)) { - _PyArg_BadArgument("setstate", 0, "int", arg); + _PyArg_BadArgument("setstate", "argument", "int", arg); goto exit; } statelong = (PyLongObject *)arg; @@ -282,7 +282,7 @@ _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderOb goto exit; } if (!PyBuffer_IsContiguous(&input, 'C')) { - _PyArg_BadArgument("decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("decode", "argument 'input'", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -345,7 +345,7 @@ _multibytecodec_MultibyteIncrementalDecoder_setstate(MultibyteIncrementalDecoder PyObject *state; if (!PyTuple_Check(arg)) { - _PyArg_BadArgument("setstate", 0, "tuple", arg); + _PyArg_BadArgument("setstate", "argument", "tuple", arg); goto exit; } state = arg; @@ -525,4 +525,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=eb95a408c4ddbfff input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5ce6fd4ca1f95620 input=a9049054013a1b77]*/ diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index c01a0e5dfadfd0..4a751f7ca55566 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -548,7 +548,7 @@ multibytecodec_encode(MultibyteCodec *codec, _multibytecodec.MultibyteCodec.encode input: object - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None Return an encoded string version of `input'. @@ -562,7 +562,7 @@ static PyObject * _multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, PyObject *input, const char *errors) -/*[clinic end generated code: output=7b26652045ba56a9 input=05f6ced3c8dd0582]*/ +/*[clinic end generated code: output=7b26652045ba56a9 input=606d0e128a577bae]*/ { MultibyteCodec_State state; PyObject *errorcb, *r, *ucvt; @@ -617,7 +617,7 @@ _multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, _multibytecodec.MultibyteCodec.decode input: Py_buffer - errors: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = None Decodes 'input'. @@ -631,7 +631,7 @@ static PyObject * _multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, Py_buffer *input, const char *errors) -/*[clinic end generated code: output=ff419f65bad6cc77 input=a7d45f87f75e5e02]*/ +/*[clinic end generated code: output=ff419f65bad6cc77 input=e0c78fc7ab190def]*/ { MultibyteCodec_State state; MultibyteDecodeBuffer buf; diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index b9daee6aae965b..17eb77334d0a73 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -119,7 +119,7 @@ PyDoc_STRVAR(_asyncio_Future_set_exception__doc__, {"set_exception", (PyCFunction)_asyncio_Future_set_exception, METH_O, _asyncio_Future_set_exception__doc__}, PyDoc_STRVAR(_asyncio_Future_add_done_callback__doc__, -"add_done_callback($self, fn, /, *, context=None)\n" +"add_done_callback($self, fn, /, *, context=)\n" "--\n" "\n" "Add a callback to be run when the future becomes done.\n" @@ -832,4 +832,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=51c50219f6a0863a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=585ba1f8de5b4103 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h index cc16d8bb228fe5..ac826bd9b5986f 100644 --- a/Modules/clinic/_bz2module.c.h +++ b/Modules/clinic/_bz2module.c.h @@ -29,7 +29,7 @@ _bz2_BZ2Compressor_compress(BZ2Compressor *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("compress", 0, "contiguous buffer", arg); + _PyArg_BadArgument("compress", "argument", "contiguous buffer", arg); goto exit; } return_value = _bz2_BZ2Compressor_compress_impl(self, &data); @@ -156,7 +156,7 @@ _bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("decompress", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("decompress", "argument 'data'", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -220,4 +220,4 @@ _bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=8e123f4eec497655 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ec3d1b3652c98823 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h index 65e24832fff6b3..772c8ca538da23 100644 --- a/Modules/clinic/_codecsmodule.c.h +++ b/Modules/clinic/_codecsmodule.c.h @@ -34,7 +34,7 @@ _codecs_lookup(PyObject *module, PyObject *arg) const char *encoding; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("lookup", 0, "str", arg); + _PyArg_BadArgument("lookup", "argument", "str", arg); goto exit; } Py_ssize_t encoding_length; @@ -93,7 +93,7 @@ _codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje } if (args[1]) { if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("encode", 2, "str", args[1]); + _PyArg_BadArgument("encode", "argument 'encoding'", "str", args[1]); goto exit; } Py_ssize_t encoding_length; @@ -110,7 +110,7 @@ _codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (!PyUnicode_Check(args[2])) { - _PyArg_BadArgument("encode", 3, "str", args[2]); + _PyArg_BadArgument("encode", "argument 'errors'", "str", args[2]); goto exit; } Py_ssize_t errors_length; @@ -170,7 +170,7 @@ _codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje } if (args[1]) { if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("decode", 2, "str", args[1]); + _PyArg_BadArgument("decode", "argument 'encoding'", "str", args[1]); goto exit; } Py_ssize_t encoding_length; @@ -187,7 +187,7 @@ _codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (!PyUnicode_Check(args[2])) { - _PyArg_BadArgument("decode", 3, "str", args[2]); + _PyArg_BadArgument("decode", "argument 'errors'", "str", args[2]); goto exit; } Py_ssize_t errors_length; @@ -225,7 +225,7 @@ _codecs__forget_codec(PyObject *module, PyObject *arg) const char *encoding; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("_forget_codec", 0, "str", arg); + _PyArg_BadArgument("_forget_codec", "argument", "str", arg); goto exit; } Py_ssize_t encoding_length; @@ -278,7 +278,7 @@ _codecs_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("escape_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("escape_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } } @@ -300,7 +300,7 @@ _codecs_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("escape_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("escape_decode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -338,7 +338,7 @@ _codecs_escape_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBytes_Check(args[0])) { - _PyArg_BadArgument("escape_encode", 1, "bytes", args[0]); + _PyArg_BadArgument("escape_encode", "argument 1", "bytes", args[0]); goto exit; } data = args[0]; @@ -360,7 +360,7 @@ _codecs_escape_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("escape_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("escape_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -397,7 +397,7 @@ _codecs_utf_7_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_7_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("utf_7_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -418,7 +418,7 @@ _codecs_utf_7_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("utf_7_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_7_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -472,7 +472,7 @@ _codecs_utf_8_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_8_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("utf_8_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -493,7 +493,7 @@ _codecs_utf_8_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("utf_8_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_8_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -547,7 +547,7 @@ _codecs_utf_16_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_16_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("utf_16_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -568,7 +568,7 @@ _codecs_utf_16_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("utf_16_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_16_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -622,7 +622,7 @@ _codecs_utf_16_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_16_le_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("utf_16_le_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -643,7 +643,7 @@ _codecs_utf_16_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar } } else { - _PyArg_BadArgument("utf_16_le_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_16_le_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -697,7 +697,7 @@ _codecs_utf_16_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_16_be_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("utf_16_be_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -718,7 +718,7 @@ _codecs_utf_16_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar } } else { - _PyArg_BadArgument("utf_16_be_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_16_be_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -774,7 +774,7 @@ _codecs_utf_16_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_16_ex_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("utf_16_ex_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -795,7 +795,7 @@ _codecs_utf_16_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar } } else { - _PyArg_BadArgument("utf_16_ex_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_16_ex_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -861,7 +861,7 @@ _codecs_utf_32_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_32_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("utf_32_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -882,7 +882,7 @@ _codecs_utf_32_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("utf_32_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_32_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -936,7 +936,7 @@ _codecs_utf_32_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_32_le_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("utf_32_le_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -957,7 +957,7 @@ _codecs_utf_32_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar } } else { - _PyArg_BadArgument("utf_32_le_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_32_le_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -1011,7 +1011,7 @@ _codecs_utf_32_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_32_be_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("utf_32_be_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -1032,7 +1032,7 @@ _codecs_utf_32_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar } } else { - _PyArg_BadArgument("utf_32_be_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_32_be_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -1088,7 +1088,7 @@ _codecs_utf_32_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_32_ex_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("utf_32_ex_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -1109,7 +1109,7 @@ _codecs_utf_32_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar } } else { - _PyArg_BadArgument("utf_32_ex_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_32_ex_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -1183,7 +1183,7 @@ _codecs_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_ goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("unicode_escape_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("unicode_escape_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } } @@ -1205,7 +1205,7 @@ _codecs_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_ } } else { - _PyArg_BadArgument("unicode_escape_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("unicode_escape_decode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -1255,7 +1255,7 @@ _codecs_raw_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ss goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("raw_unicode_escape_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("raw_unicode_escape_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } } @@ -1277,7 +1277,7 @@ _codecs_raw_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ss } } else { - _PyArg_BadArgument("raw_unicode_escape_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("raw_unicode_escape_decode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -1318,7 +1318,7 @@ _codecs_latin_1_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("latin_1_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("latin_1_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -1339,7 +1339,7 @@ _codecs_latin_1_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs } } else { - _PyArg_BadArgument("latin_1_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("latin_1_decode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -1380,7 +1380,7 @@ _codecs_ascii_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("ascii_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("ascii_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -1401,7 +1401,7 @@ _codecs_ascii_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("ascii_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("ascii_decode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -1434,7 +1434,7 @@ _codecs_charmap_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; const char *errors = NULL; - PyObject *mapping = NULL; + PyObject *mapping = Py_None; if (!_PyArg_CheckPositional("charmap_decode", nargs, 1, 3)) { goto exit; @@ -1443,7 +1443,7 @@ _codecs_charmap_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("charmap_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("charmap_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -1464,7 +1464,7 @@ _codecs_charmap_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs } } else { - _PyArg_BadArgument("charmap_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("charmap_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -1512,7 +1512,7 @@ _codecs_mbcs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("mbcs_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("mbcs_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -1533,7 +1533,7 @@ _codecs_mbcs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("mbcs_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("mbcs_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -1591,7 +1591,7 @@ _codecs_oem_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("oem_decode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("oem_decode", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -1612,7 +1612,7 @@ _codecs_oem_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("oem_decode", 2, "str or None", args[1]); + _PyArg_BadArgument("oem_decode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -1680,7 +1680,7 @@ _codecs_code_page_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("code_page_decode", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("code_page_decode", "argument 2", "contiguous buffer", args[1]); goto exit; } if (nargs < 3) { @@ -1701,7 +1701,7 @@ _codecs_code_page_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar } } else { - _PyArg_BadArgument("code_page_decode", 3, "str or None", args[2]); + _PyArg_BadArgument("code_page_decode", "argument 3", "str or None", args[2]); goto exit; } if (nargs < 4) { @@ -1765,7 +1765,7 @@ _codecs_readbuffer_encode(PyObject *module, PyObject *const *args, Py_ssize_t na goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("readbuffer_encode", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("readbuffer_encode", "argument 1", "contiguous buffer", args[0]); goto exit; } } @@ -1787,7 +1787,7 @@ _codecs_readbuffer_encode(PyObject *module, PyObject *const *args, Py_ssize_t na } } else { - _PyArg_BadArgument("readbuffer_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("readbuffer_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -1825,7 +1825,7 @@ _codecs_utf_7_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("utf_7_encode", 1, "str", args[0]); + _PyArg_BadArgument("utf_7_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -1850,7 +1850,7 @@ _codecs_utf_7_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("utf_7_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_7_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -1883,7 +1883,7 @@ _codecs_utf_8_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("utf_8_encode", 1, "str", args[0]); + _PyArg_BadArgument("utf_8_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -1908,7 +1908,7 @@ _codecs_utf_8_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("utf_8_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_8_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -1942,7 +1942,7 @@ _codecs_utf_16_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("utf_16_encode", 1, "str", args[0]); + _PyArg_BadArgument("utf_16_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -1967,7 +1967,7 @@ _codecs_utf_16_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("utf_16_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_16_encode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -2012,7 +2012,7 @@ _codecs_utf_16_le_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("utf_16_le_encode", 1, "str", args[0]); + _PyArg_BadArgument("utf_16_le_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -2037,7 +2037,7 @@ _codecs_utf_16_le_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar } } else { - _PyArg_BadArgument("utf_16_le_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_16_le_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -2070,7 +2070,7 @@ _codecs_utf_16_be_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("utf_16_be_encode", 1, "str", args[0]); + _PyArg_BadArgument("utf_16_be_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -2095,7 +2095,7 @@ _codecs_utf_16_be_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar } } else { - _PyArg_BadArgument("utf_16_be_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_16_be_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -2129,7 +2129,7 @@ _codecs_utf_32_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("utf_32_encode", 1, "str", args[0]); + _PyArg_BadArgument("utf_32_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -2154,7 +2154,7 @@ _codecs_utf_32_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("utf_32_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_32_encode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -2199,7 +2199,7 @@ _codecs_utf_32_le_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("utf_32_le_encode", 1, "str", args[0]); + _PyArg_BadArgument("utf_32_le_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -2224,7 +2224,7 @@ _codecs_utf_32_le_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar } } else { - _PyArg_BadArgument("utf_32_le_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_32_le_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -2257,7 +2257,7 @@ _codecs_utf_32_be_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("utf_32_be_encode", 1, "str", args[0]); + _PyArg_BadArgument("utf_32_be_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -2282,7 +2282,7 @@ _codecs_utf_32_be_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar } } else { - _PyArg_BadArgument("utf_32_be_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("utf_32_be_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -2315,7 +2315,7 @@ _codecs_unicode_escape_encode(PyObject *module, PyObject *const *args, Py_ssize_ goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("unicode_escape_encode", 1, "str", args[0]); + _PyArg_BadArgument("unicode_escape_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -2340,7 +2340,7 @@ _codecs_unicode_escape_encode(PyObject *module, PyObject *const *args, Py_ssize_ } } else { - _PyArg_BadArgument("unicode_escape_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("unicode_escape_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -2373,7 +2373,7 @@ _codecs_raw_unicode_escape_encode(PyObject *module, PyObject *const *args, Py_ss goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("raw_unicode_escape_encode", 1, "str", args[0]); + _PyArg_BadArgument("raw_unicode_escape_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -2398,7 +2398,7 @@ _codecs_raw_unicode_escape_encode(PyObject *module, PyObject *const *args, Py_ss } } else { - _PyArg_BadArgument("raw_unicode_escape_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("raw_unicode_escape_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -2431,7 +2431,7 @@ _codecs_latin_1_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("latin_1_encode", 1, "str", args[0]); + _PyArg_BadArgument("latin_1_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -2456,7 +2456,7 @@ _codecs_latin_1_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs } } else { - _PyArg_BadArgument("latin_1_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("latin_1_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -2489,7 +2489,7 @@ _codecs_ascii_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("ascii_encode", 1, "str", args[0]); + _PyArg_BadArgument("ascii_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -2514,7 +2514,7 @@ _codecs_ascii_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("ascii_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("ascii_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -2542,13 +2542,13 @@ _codecs_charmap_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs PyObject *return_value = NULL; PyObject *str; const char *errors = NULL; - PyObject *mapping = NULL; + PyObject *mapping = Py_None; if (!_PyArg_CheckPositional("charmap_encode", nargs, 1, 3)) { goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("charmap_encode", 1, "str", args[0]); + _PyArg_BadArgument("charmap_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -2573,7 +2573,7 @@ _codecs_charmap_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs } } else { - _PyArg_BadArgument("charmap_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("charmap_encode", "argument 2", "str or None", args[1]); goto exit; } if (nargs < 3) { @@ -2605,7 +2605,7 @@ _codecs_charmap_build(PyObject *module, PyObject *arg) PyObject *map; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("charmap_build", 0, "str", arg); + _PyArg_BadArgument("charmap_build", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -2642,7 +2642,7 @@ _codecs_mbcs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("mbcs_encode", 1, "str", args[0]); + _PyArg_BadArgument("mbcs_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -2667,7 +2667,7 @@ _codecs_mbcs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("mbcs_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("mbcs_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -2703,7 +2703,7 @@ _codecs_oem_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("oem_encode", 1, "str", args[0]); + _PyArg_BadArgument("oem_encode", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -2728,7 +2728,7 @@ _codecs_oem_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("oem_encode", 2, "str or None", args[1]); + _PyArg_BadArgument("oem_encode", "argument 2", "str or None", args[1]); goto exit; } skip_optional: @@ -2775,7 +2775,7 @@ _codecs_code_page_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("code_page_encode", 2, "str", args[1]); + _PyArg_BadArgument("code_page_encode", "argument 2", "str", args[1]); goto exit; } if (PyUnicode_READY(args[1]) == -1) { @@ -2800,7 +2800,7 @@ _codecs_code_page_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar } } else { - _PyArg_BadArgument("code_page_encode", 3, "str or None", args[2]); + _PyArg_BadArgument("code_page_encode", "argument 3", "str or None", args[2]); goto exit; } skip_optional: @@ -2840,7 +2840,7 @@ _codecs_register_error(PyObject *module, PyObject *const *args, Py_ssize_t nargs goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("register_error", 1, "str", args[0]); + _PyArg_BadArgument("register_error", "argument 1", "str", args[0]); goto exit; } Py_ssize_t errors_length; @@ -2881,7 +2881,7 @@ _codecs_lookup_error(PyObject *module, PyObject *arg) const char *name; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("lookup_error", 0, "str", arg); + _PyArg_BadArgument("lookup_error", "argument", "str", arg); goto exit; } Py_ssize_t name_length; @@ -2922,4 +2922,4 @@ _codecs_lookup_error(PyObject *module, PyObject *arg) #ifndef _CODECS_CODE_PAGE_ENCODE_METHODDEF #define _CODECS_CODE_PAGE_ENCODE_METHODDEF #endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */ -/*[clinic end generated code: output=da3c47709a55a05e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=51b42d170889524c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_collectionsmodule.c.h b/Modules/clinic/_collectionsmodule.c.h index ed3b1b50f9b582..c3ba1a6698571d 100644 --- a/Modules/clinic/_collectionsmodule.c.h +++ b/Modules/clinic/_collectionsmodule.c.h @@ -2,6 +2,37 @@ preserve [clinic start generated code]*/ +PyDoc_STRVAR(_collections__count_elements__doc__, +"_count_elements($module, mapping, iterable, /)\n" +"--\n" +"\n" +"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__}, + +static PyObject * +_collections__count_elements_impl(PyObject *module, PyObject *mapping, + PyObject *iterable); + +static PyObject * +_collections__count_elements(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *mapping; + PyObject *iterable; + + if (!_PyArg_CheckPositional("_count_elements", nargs, 2, 2)) { + goto exit; + } + mapping = args[0]; + iterable = args[1]; + return_value = _collections__count_elements_impl(module, mapping, iterable); + +exit: + return return_value; +} + static PyObject * tuplegetter_new_impl(PyTypeObject *type, Py_ssize_t index, PyObject *doc); @@ -42,4 +73,4 @@ tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=51bd572577ca7111 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9d2bfcc9df5faf35 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cryptmodule.c.h b/Modules/clinic/_cryptmodule.c.h index 2fcb0c1bf12c3a..ea91d7c130b8cd 100644 --- a/Modules/clinic/_cryptmodule.c.h +++ b/Modules/clinic/_cryptmodule.c.h @@ -30,7 +30,7 @@ crypt_crypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("crypt", 1, "str", args[0]); + _PyArg_BadArgument("crypt", "argument 1", "str", args[0]); goto exit; } Py_ssize_t word_length; @@ -43,7 +43,7 @@ crypt_crypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("crypt", 2, "str", args[1]); + _PyArg_BadArgument("crypt", "argument 2", "str", args[1]); goto exit; } Py_ssize_t salt_length; @@ -60,4 +60,4 @@ crypt_crypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=3f75d4d4be4dddbb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=549de0d43b030126 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h index 0df442056ea9f3..9840ed86e79129 100644 --- a/Modules/clinic/_curses_panel.c.h +++ b/Modules/clinic/_curses_panel.c.h @@ -214,7 +214,7 @@ _curses_panel_panel_replace(PyCursesPanelObject *self, PyObject *arg) PyCursesWindowObject *win; if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { - _PyArg_BadArgument("replace", 0, (&PyCursesWindow_Type)->tp_name, arg); + _PyArg_BadArgument("replace", "argument", (&PyCursesWindow_Type)->tp_name, arg); goto exit; } win = (PyCursesWindowObject *)arg; @@ -288,7 +288,7 @@ _curses_panel_new_panel(PyObject *module, PyObject *arg) PyCursesWindowObject *win; if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { - _PyArg_BadArgument("new_panel", 0, (&PyCursesWindow_Type)->tp_name, arg); + _PyArg_BadArgument("new_panel", "argument", (&PyCursesWindow_Type)->tp_name, arg); goto exit; } win = (PyCursesWindowObject *)arg; @@ -335,4 +335,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _curses_panel_update_panels_impl(module); } -/*[clinic end generated code: output=3cc16062281b7e07 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d96dc1fd68e898d9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index 6837eac3909695..ad93e6a0ca0220 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -2521,7 +2521,7 @@ _curses_ungetmouse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyLong_Check(args[4])) { - _PyArg_BadArgument("ungetmouse", 5, "int", args[4]); + _PyArg_BadArgument("ungetmouse", "argument 5", "int", args[4]); goto exit; } bstate = PyLong_AsUnsignedLongMask(args[4]); @@ -3017,7 +3017,7 @@ _curses_setupterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO } } else { - _PyArg_BadArgument("setupterm", 1, "str or None", args[0]); + _PyArg_BadArgument("setupterm", "argument 'term'", "str or None", args[0]); goto exit; } if (!--noptargs) { @@ -3326,7 +3326,7 @@ _curses_mousemask(PyObject *module, PyObject *arg) unsigned long newmask; if (!PyLong_Check(arg)) { - _PyArg_BadArgument("mousemask", 0, "int", arg); + _PyArg_BadArgument("mousemask", "argument", "int", arg); goto exit; } newmask = PyLong_AsUnsignedLongMask(arg); @@ -4201,7 +4201,7 @@ _curses_tigetflag(PyObject *module, PyObject *arg) const char *capname; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("tigetflag", 0, "str", arg); + _PyArg_BadArgument("tigetflag", "argument", "str", arg); goto exit; } Py_ssize_t capname_length; @@ -4244,7 +4244,7 @@ _curses_tigetnum(PyObject *module, PyObject *arg) const char *capname; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("tigetnum", 0, "str", arg); + _PyArg_BadArgument("tigetnum", "argument", "str", arg); goto exit; } Py_ssize_t capname_length; @@ -4287,7 +4287,7 @@ _curses_tigetstr(PyObject *module, PyObject *arg) const char *capname; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("tigetstr", 0, "str", arg); + _PyArg_BadArgument("tigetstr", "argument", "str", arg); goto exit; } Py_ssize_t capname_length; @@ -4569,4 +4569,4 @@ _curses_use_default_colors(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=1350eeb0c1e06af6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e5b3502f1d38dff0 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h index e54c69cf708294..a7d735085068de 100644 --- a/Modules/clinic/_dbmmodule.c.h +++ b/Modules/clinic/_dbmmodule.c.h @@ -136,7 +136,7 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("open", 1, "str", args[0]); + _PyArg_BadArgument("open", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -147,7 +147,7 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto skip_optional; } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("open", 2, "str", args[1]); + _PyArg_BadArgument("open", "argument 2", "str", args[1]); goto exit; } Py_ssize_t flags_length; @@ -177,4 +177,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=7f5d30ef5d820b8a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7ced103488cbca7a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index 0f55480140b315..0bc4bb5d15ce7e 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -20,7 +20,7 @@ _elementtree_Element_append(ElementObject *self, PyObject *arg) PyObject *subelement; if (!PyObject_TypeCheck(arg, &Element_Type)) { - _PyArg_BadArgument("append", 0, (&Element_Type)->tp_name, arg); + _PyArg_BadArgument("append", "argument", (&Element_Type)->tp_name, arg); goto exit; } subelement = arg; @@ -82,7 +82,7 @@ _elementtree_Element___deepcopy__(ElementObject *self, PyObject *arg) PyObject *memo; if (!PyDict_Check(arg)) { - _PyArg_BadArgument("__deepcopy__", 0, "dict", arg); + _PyArg_BadArgument("__deepcopy__", "argument", "dict", arg); goto exit; } memo = arg; @@ -501,7 +501,7 @@ _elementtree_Element_insert(ElementObject *self, PyObject *const *args, Py_ssize index = ival; } if (!PyObject_TypeCheck(args[1], &Element_Type)) { - _PyArg_BadArgument("insert", 2, (&Element_Type)->tp_name, args[1]); + _PyArg_BadArgument("insert", "argument 2", (&Element_Type)->tp_name, args[1]); goto exit; } subelement = args[1]; @@ -593,7 +593,7 @@ _elementtree_Element_remove(ElementObject *self, PyObject *arg) PyObject *subelement; if (!PyObject_TypeCheck(arg, &Element_Type)) { - _PyArg_BadArgument("remove", 0, (&Element_Type)->tp_name, arg); + _PyArg_BadArgument("remove", "argument", (&Element_Type)->tp_name, arg); goto exit; } subelement = arg; @@ -650,9 +650,9 @@ _elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwar PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; - PyObject *element_factory = NULL; - PyObject *comment_factory = NULL; - PyObject *pi_factory = NULL; + PyObject *element_factory = Py_None; + PyObject *comment_factory = Py_None; + PyObject *pi_factory = Py_None; int insert_comments = 0; int insert_pis = 0; @@ -892,7 +892,7 @@ _elementtree_XMLParser___init__(PyObject *self, PyObject *args, PyObject *kwargs } } else { - _PyArg_BadArgument("XMLParser", 2, "str or None", fastargs[1]); + _PyArg_BadArgument("XMLParser", "argument 'encoding'", "str or None", fastargs[1]); goto exit; } skip_optional_kwonly: @@ -969,4 +969,4 @@ _elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *const *args, exit: return return_value; } -/*[clinic end generated code: output=386a68425d072b5c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1443ed7bb9f9e03e input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_gdbmmodule.c.h b/Modules/clinic/_gdbmmodule.c.h index 15f47dc70dc65a..aa37a24d3b2115 100644 --- a/Modules/clinic/_gdbmmodule.c.h +++ b/Modules/clinic/_gdbmmodule.c.h @@ -257,7 +257,7 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("open", 1, "str", args[0]); + _PyArg_BadArgument("open", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -268,7 +268,7 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto skip_optional; } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("open", 2, "str", args[1]); + _PyArg_BadArgument("open", "argument 2", "str", args[1]); goto exit; } Py_ssize_t flags_length; @@ -298,4 +298,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=0a72598e5a3acd60 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2766471b2fa1a816 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h index 5596f13e508f7d..9aaea47e8328ed 100644 --- a/Modules/clinic/_hashopenssl.c.h +++ b/Modules/clinic/_hashopenssl.c.h @@ -109,7 +109,227 @@ EVP_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn return return_value; } -#if ((OPENSSL_VERSION_NUMBER >= 0x10000000 && !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA))) +PyDoc_STRVAR(_hashlib_openssl_md5__doc__, +"openssl_md5($module, /, string=b\'\')\n" +"--\n" +"\n" +"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__}, + +static PyObject * +_hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj); + +static PyObject * +_hashlib_openssl_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "openssl_md5", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[0]; +skip_optional_pos: + return_value = _hashlib_openssl_md5_impl(module, data_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hashlib_openssl_sha1__doc__, +"openssl_sha1($module, /, string=b\'\')\n" +"--\n" +"\n" +"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__}, + +static PyObject * +_hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj); + +static PyObject * +_hashlib_openssl_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha1", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[0]; +skip_optional_pos: + return_value = _hashlib_openssl_sha1_impl(module, data_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hashlib_openssl_sha224__doc__, +"openssl_sha224($module, /, string=b\'\')\n" +"--\n" +"\n" +"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__}, + +static PyObject * +_hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj); + +static PyObject * +_hashlib_openssl_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha224", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[0]; +skip_optional_pos: + return_value = _hashlib_openssl_sha224_impl(module, data_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hashlib_openssl_sha256__doc__, +"openssl_sha256($module, /, string=b\'\')\n" +"--\n" +"\n" +"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__}, + +static PyObject * +_hashlib_openssl_sha256_impl(PyObject *module, PyObject *data_obj); + +static PyObject * +_hashlib_openssl_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha256", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[0]; +skip_optional_pos: + return_value = _hashlib_openssl_sha256_impl(module, data_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hashlib_openssl_sha384__doc__, +"openssl_sha384($module, /, string=b\'\')\n" +"--\n" +"\n" +"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__}, + +static PyObject * +_hashlib_openssl_sha384_impl(PyObject *module, PyObject *data_obj); + +static PyObject * +_hashlib_openssl_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha384", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[0]; +skip_optional_pos: + return_value = _hashlib_openssl_sha384_impl(module, data_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hashlib_openssl_sha512__doc__, +"openssl_sha512($module, /, string=b\'\')\n" +"--\n" +"\n" +"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__}, + +static PyObject * +_hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj); + +static PyObject * +_hashlib_openssl_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha512", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[0]; +skip_optional_pos: + return_value = _hashlib_openssl_sha512_impl(module, data_obj); + +exit: + return return_value; +} PyDoc_STRVAR(pbkdf2_hmac__doc__, "pbkdf2_hmac($module, /, hash_name, password, salt, iterations,\n" @@ -145,7 +365,7 @@ pbkdf2_hmac(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("pbkdf2_hmac", 1, "str", args[0]); + _PyArg_BadArgument("pbkdf2_hmac", "argument 'hash_name'", "str", args[0]); goto exit; } Py_ssize_t hash_name_length; @@ -161,14 +381,14 @@ pbkdf2_hmac(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } if (!PyBuffer_IsContiguous(&password, 'C')) { - _PyArg_BadArgument("pbkdf2_hmac", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("pbkdf2_hmac", "argument 'password'", "contiguous buffer", args[1]); goto exit; } if (PyObject_GetBuffer(args[2], &salt, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&salt, 'C')) { - _PyArg_BadArgument("pbkdf2_hmac", 3, "contiguous buffer", args[2]); + _PyArg_BadArgument("pbkdf2_hmac", "argument 'salt'", "contiguous buffer", args[2]); goto exit; } if (PyFloat_Check(args[3])) { @@ -200,8 +420,6 @@ pbkdf2_hmac(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject return return_value; } -#endif /* ((OPENSSL_VERSION_NUMBER >= 0x10000000 && !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA))) */ - #if (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) PyDoc_STRVAR(_hashlib_scrypt__doc__, @@ -243,7 +461,7 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto exit; } if (!PyBuffer_IsContiguous(&password, 'C')) { - _PyArg_BadArgument("scrypt", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("scrypt", "argument 'password'", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -254,7 +472,7 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto exit; } if (!PyBuffer_IsContiguous(&salt, 'C')) { - _PyArg_BadArgument("scrypt", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("scrypt", "argument 'salt'", "contiguous buffer", args[1]); goto exit; } if (!--noptargs) { @@ -263,7 +481,7 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } if (args[2]) { if (!PyLong_Check(args[2])) { - _PyArg_BadArgument("scrypt", 3, "int", args[2]); + _PyArg_BadArgument("scrypt", "argument 'n'", "int", args[2]); goto exit; } n_obj = args[2]; @@ -273,7 +491,7 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } if (args[3]) { if (!PyLong_Check(args[3])) { - _PyArg_BadArgument("scrypt", 4, "int", args[3]); + _PyArg_BadArgument("scrypt", "argument 'r'", "int", args[3]); goto exit; } r_obj = args[3]; @@ -283,7 +501,7 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } if (args[4]) { if (!PyLong_Check(args[4])) { - _PyArg_BadArgument("scrypt", 5, "int", args[4]); + _PyArg_BadArgument("scrypt", "argument 'p'", "int", args[4]); goto exit; } p_obj = args[4]; @@ -364,18 +582,18 @@ _hashlib_hmac_digest(PyObject *module, PyObject *const *args, Py_ssize_t nargs, goto exit; } if (!PyBuffer_IsContiguous(&key, 'C')) { - _PyArg_BadArgument("hmac_digest", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("hmac_digest", "argument 'key'", "contiguous buffer", args[0]); goto exit; } if (PyObject_GetBuffer(args[1], &msg, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&msg, 'C')) { - _PyArg_BadArgument("hmac_digest", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("hmac_digest", "argument 'msg'", "contiguous buffer", args[1]); goto exit; } if (!PyUnicode_Check(args[2])) { - _PyArg_BadArgument("hmac_digest", 3, "str", args[2]); + _PyArg_BadArgument("hmac_digest", "argument 'digest'", "str", args[2]); goto exit; } Py_ssize_t digest_length; @@ -402,11 +620,7 @@ _hashlib_hmac_digest(PyObject *module, PyObject *const *args, Py_ssize_t nargs, return return_value; } -#ifndef PBKDF2_HMAC_METHODDEF - #define PBKDF2_HMAC_METHODDEF -#endif /* !defined(PBKDF2_HMAC_METHODDEF) */ - #ifndef _HASHLIB_SCRYPT_METHODDEF #define _HASHLIB_SCRYPT_METHODDEF #endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ -/*[clinic end generated code: output=5955ec791260045a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=38c2637f67e9bb79 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h index 68aa770d41f8a9..82ef4d517d83c5 100644 --- a/Modules/clinic/_lzmamodule.c.h +++ b/Modules/clinic/_lzmamodule.c.h @@ -29,7 +29,7 @@ _lzma_LZMACompressor_compress(Compressor *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("compress", 0, "contiguous buffer", arg); + _PyArg_BadArgument("compress", "argument", "contiguous buffer", arg); goto exit; } return_value = _lzma_LZMACompressor_compress_impl(self, &data); @@ -110,7 +110,7 @@ _lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *const *args, Py_ goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("decompress", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("decompress", "argument 'data'", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -321,7 +321,7 @@ _lzma__decode_filter_properties(PyObject *module, PyObject *const *args, Py_ssiz goto exit; } if (!PyBuffer_IsContiguous(&encoded_props, 'C')) { - _PyArg_BadArgument("_decode_filter_properties", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("_decode_filter_properties", "argument 2", "contiguous buffer", args[1]); goto exit; } return_value = _lzma__decode_filter_properties_impl(module, filter_id, &encoded_props); @@ -334,4 +334,4 @@ _lzma__decode_filter_properties(PyObject *module, PyObject *const *args, Py_ssiz return return_value; } -/*[clinic end generated code: output=1a290aa478603107 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f7477a10e86a717d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h index 8ac723fd43a681..9da3f1195a3bf2 100644 --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -112,9 +112,9 @@ _pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; PyObject *file; - PyObject *protocol = NULL; + PyObject *protocol = Py_None; int fix_imports = 1; - PyObject *buffer_callback = NULL; + PyObject *buffer_callback = Py_None; fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 4, 0, argsbuf); if (!fastargs) { @@ -292,7 +292,7 @@ _pickle_Unpickler___sizeof__(UnpicklerObject *self, PyObject *Py_UNUSED(ignored) PyDoc_STRVAR(_pickle_Unpickler___init____doc__, "Unpickler(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\',\n" -" buffers=None)\n" +" buffers=())\n" "--\n" "\n" "This takes a binary file for reading a pickle data stream.\n" @@ -356,7 +356,7 @@ _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) } if (fastargs[2]) { if (!PyUnicode_Check(fastargs[2])) { - _PyArg_BadArgument("Unpickler", 3, "str", fastargs[2]); + _PyArg_BadArgument("Unpickler", "argument 'encoding'", "str", fastargs[2]); goto exit; } Py_ssize_t encoding_length; @@ -374,7 +374,7 @@ _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) } if (fastargs[3]) { if (!PyUnicode_Check(fastargs[3])) { - _PyArg_BadArgument("Unpickler", 4, "str", fastargs[3]); + _PyArg_BadArgument("Unpickler", "argument 'errors'", "str", fastargs[3]); goto exit; } Py_ssize_t errors_length; @@ -502,9 +502,9 @@ _pickle_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *obj; PyObject *file; - PyObject *protocol = NULL; + PyObject *protocol = Py_None; int fix_imports = 1; - PyObject *buffer_callback = NULL; + PyObject *buffer_callback = Py_None; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); if (!args) { @@ -582,9 +582,9 @@ _pickle_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *obj; - PyObject *protocol = NULL; + PyObject *protocol = Py_None; int fix_imports = 1; - PyObject *buffer_callback = NULL; + PyObject *buffer_callback = Py_None; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { @@ -623,7 +623,7 @@ _pickle_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec PyDoc_STRVAR(_pickle_load__doc__, "load($module, /, file, *, fix_imports=True, encoding=\'ASCII\',\n" -" errors=\'strict\', buffers=None)\n" +" errors=\'strict\', buffers=())\n" "--\n" "\n" "Read and return an object from the pickle data stored in a file.\n" @@ -691,7 +691,7 @@ _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject } if (args[2]) { if (!PyUnicode_Check(args[2])) { - _PyArg_BadArgument("load", 3, "str", args[2]); + _PyArg_BadArgument("load", "argument 'encoding'", "str", args[2]); goto exit; } Py_ssize_t encoding_length; @@ -709,7 +709,7 @@ _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject } if (args[3]) { if (!PyUnicode_Check(args[3])) { - _PyArg_BadArgument("load", 4, "str", args[3]); + _PyArg_BadArgument("load", "argument 'errors'", "str", args[3]); goto exit; } Py_ssize_t errors_length; @@ -735,7 +735,7 @@ _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject PyDoc_STRVAR(_pickle_loads__doc__, "loads($module, /, data, *, fix_imports=True, encoding=\'ASCII\',\n" -" errors=\'strict\', buffers=None)\n" +" errors=\'strict\', buffers=())\n" "--\n" "\n" "Read and return an object from the given pickle data.\n" @@ -794,7 +794,7 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec } if (args[2]) { if (!PyUnicode_Check(args[2])) { - _PyArg_BadArgument("loads", 3, "str", args[2]); + _PyArg_BadArgument("loads", "argument 'encoding'", "str", args[2]); goto exit; } Py_ssize_t encoding_length; @@ -812,7 +812,7 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec } if (args[3]) { if (!PyUnicode_Check(args[3])) { - _PyArg_BadArgument("loads", 4, "str", args[3]); + _PyArg_BadArgument("loads", "argument 'errors'", "str", args[3]); goto exit; } Py_ssize_t errors_length; @@ -835,4 +835,4 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=8dc0e862f96c4afe input=a9049054013a1b77]*/ +/*[clinic end generated code: output=de075ec48d4ee0e1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_sre.c.h b/Modules/clinic/_sre.c.h index 9c08dec4541a47..d398a8504ba418 100644 --- a/Modules/clinic/_sre.c.h +++ b/Modules/clinic/_sre.c.h @@ -894,7 +894,7 @@ _sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } if (!PyList_Check(args[2])) { - _PyArg_BadArgument("compile", 3, "list", args[2]); + _PyArg_BadArgument("compile", "argument 'code'", "list", args[2]); goto exit; } code = args[2]; @@ -916,12 +916,12 @@ _sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject groups = ival; } if (!PyDict_Check(args[4])) { - _PyArg_BadArgument("compile", 5, "dict", args[4]); + _PyArg_BadArgument("compile", "argument 'groupindex'", "dict", args[4]); goto exit; } groupindex = args[4]; if (!PyTuple_Check(args[5])) { - _PyArg_BadArgument("compile", 6, "tuple", args[5]); + _PyArg_BadArgument("compile", "argument 'indexgroup'", "tuple", args[5]); goto exit; } indexgroup = args[5]; @@ -1207,4 +1207,4 @@ _sre_SRE_Scanner_search(ScannerObject *self, PyObject *Py_UNUSED(ignored)) { return _sre_SRE_Scanner_search_impl(self); } -/*[clinic end generated code: output=67b702da5bdc9cac input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1adeddce58ae284c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index b1012f7aee2ea7..ce8669ae212edb 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -222,7 +222,7 @@ _ssl__SSLSocket_write(PySSLSocket *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&b, 'C')) { - _PyArg_BadArgument("write", 0, "contiguous buffer", arg); + _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); goto exit; } return_value = _ssl__SSLSocket_write_impl(self, &b); @@ -353,7 +353,7 @@ _ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py goto skip_optional_pos; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("get_channel_binding", 1, "str", args[0]); + _PyArg_BadArgument("get_channel_binding", "argument 'cb_type'", "str", args[0]); goto exit; } Py_ssize_t cb_type_length; @@ -439,7 +439,7 @@ _ssl__SSLContext_set_ciphers(PySSLContext *self, PyObject *arg) const char *cipherlist; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("set_ciphers", 0, "str", arg); + _PyArg_BadArgument("set_ciphers", "argument", "str", arg); goto exit; } Py_ssize_t cipherlist_length; @@ -500,7 +500,7 @@ _ssl__SSLContext__set_npn_protocols(PySSLContext *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&protos, 'C')) { - _PyArg_BadArgument("_set_npn_protocols", 0, "contiguous buffer", arg); + _PyArg_BadArgument("_set_npn_protocols", "argument", "contiguous buffer", arg); goto exit; } return_value = _ssl__SSLContext__set_npn_protocols_impl(self, &protos); @@ -536,7 +536,7 @@ _ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&protos, 'C')) { - _PyArg_BadArgument("_set_alpn_protocols", 0, "contiguous buffer", arg); + _PyArg_BadArgument("_set_alpn_protocols", "argument", "contiguous buffer", arg); goto exit; } return_value = _ssl__SSLContext__set_alpn_protocols_impl(self, &protos); @@ -571,8 +571,8 @@ _ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject *const *args, Py_s PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *certfile; - PyObject *keyfile = NULL; - PyObject *password = NULL; + PyObject *keyfile = Py_None; + PyObject *password = Py_None; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { @@ -618,9 +618,9 @@ _ssl__SSLContext_load_verify_locations(PySSLContext *self, PyObject *const *args static _PyArg_Parser _parser = {NULL, _keywords, "load_verify_locations", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *cafile = NULL; - PyObject *capath = NULL; - PyObject *cadata = NULL; + PyObject *cafile = Py_None; + PyObject *capath = Py_None; + PyObject *cadata = Py_None; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 3, 0, argsbuf); if (!args) { @@ -690,7 +690,7 @@ _ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssiz goto exit; } if (!PyObject_TypeCheck(args[0], PySocketModule.Sock_Type)) { - _PyArg_BadArgument("_wrap_socket", 1, (PySocketModule.Sock_Type)->tp_name, args[0]); + _PyArg_BadArgument("_wrap_socket", "argument 'sock'", (PySocketModule.Sock_Type)->tp_name, args[0]); goto exit; } sock = args[0]; @@ -765,12 +765,12 @@ _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t goto exit; } if (!PyObject_TypeCheck(args[0], &PySSLMemoryBIO_Type)) { - _PyArg_BadArgument("_wrap_bio", 1, (&PySSLMemoryBIO_Type)->tp_name, args[0]); + _PyArg_BadArgument("_wrap_bio", "argument 'incoming'", (&PySSLMemoryBIO_Type)->tp_name, args[0]); goto exit; } incoming = (PySSLMemoryBIO *)args[0]; if (!PyObject_TypeCheck(args[1], &PySSLMemoryBIO_Type)) { - _PyArg_BadArgument("_wrap_bio", 2, (&PySSLMemoryBIO_Type)->tp_name, args[1]); + _PyArg_BadArgument("_wrap_bio", "argument 'outgoing'", (&PySSLMemoryBIO_Type)->tp_name, args[1]); goto exit; } outgoing = (PySSLMemoryBIO *)args[1]; @@ -1017,7 +1017,7 @@ _ssl_MemoryBIO_write(PySSLMemoryBIO *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&b, 'C')) { - _PyArg_BadArgument("write", 0, "contiguous buffer", arg); + _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); goto exit; } return_value = _ssl_MemoryBIO_write_impl(self, &b); @@ -1089,13 +1089,19 @@ _ssl_RAND_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&view, 'C')) { - _PyArg_BadArgument("RAND_add", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("RAND_add", "argument 1", "contiguous buffer", args[0]); goto exit; } } - entropy = PyFloat_AsDouble(args[1]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[1])) { + entropy = PyFloat_AS_DOUBLE(args[1]); + } + else + { + entropy = PyFloat_AsDouble(args[1]); + if (entropy == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = _ssl_RAND_add_impl(module, &view, entropy); @@ -1283,7 +1289,7 @@ _ssl_txt2obj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("txt2obj", 1, "str", args[0]); + _PyArg_BadArgument("txt2obj", "argument 'txt'", "str", args[0]); goto exit; } Py_ssize_t txt_length; @@ -1376,7 +1382,7 @@ _ssl_enum_certificates(PyObject *module, PyObject *const *args, Py_ssize_t nargs goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("enum_certificates", 1, "str", args[0]); + _PyArg_BadArgument("enum_certificates", "argument 'store_name'", "str", args[0]); goto exit; } Py_ssize_t store_name_length; @@ -1429,7 +1435,7 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("enum_crls", 1, "str", args[0]); + _PyArg_BadArgument("enum_crls", "argument 'store_name'", "str", args[0]); goto exit; } Py_ssize_t store_name_length; @@ -1476,4 +1482,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=a399d0eb393b6fab input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a4aeb3f92a091c64 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_statisticsmodule.c.h b/Modules/clinic/_statisticsmodule.c.h new file mode 100644 index 00000000000000..5ff01efddcde89 --- /dev/null +++ b/Modules/clinic/_statisticsmodule.c.h @@ -0,0 +1,68 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +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__}, + +static double +_statistics__normal_dist_inv_cdf_impl(PyObject *module, double p, double mu, + double sigma); + +static PyObject * +_statistics__normal_dist_inv_cdf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + double p; + double mu; + double sigma; + double _return_value; + + if (!_PyArg_CheckPositional("_normal_dist_inv_cdf", nargs, 3, 3)) { + goto exit; + } + if (PyFloat_CheckExact(args[0])) { + p = PyFloat_AS_DOUBLE(args[0]); + } + else + { + p = PyFloat_AsDouble(args[0]); + if (p == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[1])) { + mu = PyFloat_AS_DOUBLE(args[1]); + } + else + { + mu = PyFloat_AsDouble(args[1]); + if (mu == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[2])) { + sigma = PyFloat_AS_DOUBLE(args[2]); + } + else + { + sigma = PyFloat_AsDouble(args[2]); + if (sigma == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + _return_value = _statistics__normal_dist_inv_cdf_impl(module, p, mu, sigma); + if ((_return_value == -1.0) && PyErr_Occurred()) { + goto exit; + } + return_value = PyFloat_FromDouble(_return_value); + +exit: + return return_value; +} +/*[clinic end generated code: output=c5826928a238326c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_struct.c.h b/Modules/clinic/_struct.c.h index 908c44266c4ec6..36c4b4046cd739 100644 --- a/Modules/clinic/_struct.c.h +++ b/Modules/clinic/_struct.c.h @@ -65,7 +65,7 @@ Struct_unpack(PyStructObject *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("unpack", 0, "contiguous buffer", arg); + _PyArg_BadArgument("unpack", "argument", "contiguous buffer", arg); goto exit; } return_value = Struct_unpack_impl(self, &buffer); @@ -118,7 +118,7 @@ Struct_unpack_from(PyStructObject *self, PyObject *const *args, Py_ssize_t nargs goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("unpack_from", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("unpack_from", "argument 'buffer'", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -253,7 +253,7 @@ unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("unpack", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("unpack", "argument 2", "contiguous buffer", args[1]); goto exit; } return_value = unpack_impl(module, s_object, &buffer); @@ -309,7 +309,7 @@ unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("unpack_from", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("unpack_from", "argument 'buffer'", "contiguous buffer", args[1]); goto exit; } if (!noptargs) { @@ -386,4 +386,4 @@ iter_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -/*[clinic end generated code: output=b642e1002d25ebdd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6a6228cfc4b7099c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h index 0a3e7ff5fc9686..73c3faeaf962e0 100644 --- a/Modules/clinic/_tkinter.c.h +++ b/Modules/clinic/_tkinter.c.h @@ -20,7 +20,7 @@ _tkinter_tkapp_eval(TkappObject *self, PyObject *arg) const char *script; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("eval", 0, "str", arg); + _PyArg_BadArgument("eval", "argument", "str", arg); goto exit; } Py_ssize_t script_length; @@ -56,7 +56,7 @@ _tkinter_tkapp_evalfile(TkappObject *self, PyObject *arg) const char *fileName; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("evalfile", 0, "str", arg); + _PyArg_BadArgument("evalfile", "argument", "str", arg); goto exit; } Py_ssize_t fileName_length; @@ -92,7 +92,7 @@ _tkinter_tkapp_record(TkappObject *self, PyObject *arg) const char *script; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("record", 0, "str", arg); + _PyArg_BadArgument("record", "argument", "str", arg); goto exit; } Py_ssize_t script_length; @@ -128,7 +128,7 @@ _tkinter_tkapp_adderrorinfo(TkappObject *self, PyObject *arg) const char *msg; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("adderrorinfo", 0, "str", arg); + _PyArg_BadArgument("adderrorinfo", "argument", "str", arg); goto exit; } Py_ssize_t msg_length; @@ -188,7 +188,7 @@ _tkinter_tkapp_exprstring(TkappObject *self, PyObject *arg) const char *s; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("exprstring", 0, "str", arg); + _PyArg_BadArgument("exprstring", "argument", "str", arg); goto exit; } Py_ssize_t s_length; @@ -224,7 +224,7 @@ _tkinter_tkapp_exprlong(TkappObject *self, PyObject *arg) const char *s; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("exprlong", 0, "str", arg); + _PyArg_BadArgument("exprlong", "argument", "str", arg); goto exit; } Py_ssize_t s_length; @@ -260,7 +260,7 @@ _tkinter_tkapp_exprdouble(TkappObject *self, PyObject *arg) const char *s; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("exprdouble", 0, "str", arg); + _PyArg_BadArgument("exprdouble", "argument", "str", arg); goto exit; } Py_ssize_t s_length; @@ -296,7 +296,7 @@ _tkinter_tkapp_exprboolean(TkappObject *self, PyObject *arg) const char *s; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("exprboolean", 0, "str", arg); + _PyArg_BadArgument("exprboolean", "argument", "str", arg); goto exit; } Py_ssize_t s_length; @@ -353,7 +353,7 @@ _tkinter_tkapp_createcommand(TkappObject *self, PyObject *const *args, Py_ssize_ goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("createcommand", 1, "str", args[0]); + _PyArg_BadArgument("createcommand", "argument 1", "str", args[0]); goto exit; } Py_ssize_t name_length; @@ -390,7 +390,7 @@ _tkinter_tkapp_deletecommand(TkappObject *self, PyObject *arg) const char *name; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("deletecommand", 0, "str", arg); + _PyArg_BadArgument("deletecommand", "argument", "str", arg); goto exit; } Py_ssize_t name_length; @@ -674,7 +674,7 @@ PyDoc_STRVAR(_tkinter__flatten__doc__, {"_flatten", (PyCFunction)_tkinter__flatten, METH_O, _tkinter__flatten__doc__}, PyDoc_STRVAR(_tkinter_create__doc__, -"create($module, screenName=None, baseName=None, className=\'Tk\',\n" +"create($module, screenName=None, baseName=\'\', className=\'Tk\',\n" " interactive=False, wantobjects=False, wantTk=True, sync=False,\n" " use=None, /)\n" "--\n" @@ -702,7 +702,7 @@ _tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; const char *screenName = NULL; - const char *baseName = NULL; + const char *baseName = ""; const char *className = "Tk"; int interactive = 0; int wantobjects = 0; @@ -731,14 +731,14 @@ _tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("create", 1, "str or None", args[0]); + _PyArg_BadArgument("create", "argument 1", "str or None", args[0]); goto exit; } if (nargs < 2) { goto skip_optional; } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("create", 2, "str", args[1]); + _PyArg_BadArgument("create", "argument 2", "str", args[1]); goto exit; } Py_ssize_t baseName_length; @@ -754,7 +754,7 @@ _tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto skip_optional; } if (!PyUnicode_Check(args[2])) { - _PyArg_BadArgument("create", 3, "str", args[2]); + _PyArg_BadArgument("create", "argument 3", "str", args[2]); goto exit; } Py_ssize_t className_length; @@ -832,7 +832,7 @@ _tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } else { - _PyArg_BadArgument("create", 8, "str or None", args[7]); + _PyArg_BadArgument("create", "argument 8", "str or None", args[7]); goto exit; } skip_optional: @@ -912,4 +912,4 @@ _tkinter_getbusywaitinterval(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #endif /* !defined(_TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF) */ -/*[clinic end generated code: output=2cf95f0101f3dbca input=a9049054013a1b77]*/ +/*[clinic end generated code: output=492b8b833fe54bc9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_weakref.c.h b/Modules/clinic/_weakref.c.h index aa0d77f7180e5e..c3a908fa6a139e 100644 --- a/Modules/clinic/_weakref.c.h +++ b/Modules/clinic/_weakref.c.h @@ -54,7 +54,7 @@ _weakref__remove_dead_weakref(PyObject *module, PyObject *const *args, Py_ssize_ goto exit; } if (!PyDict_Check(args[0])) { - _PyArg_BadArgument("_remove_dead_weakref", 1, "dict", args[0]); + _PyArg_BadArgument("_remove_dead_weakref", "argument 1", "dict", args[0]); goto exit; } dct = args[0]; @@ -64,4 +64,4 @@ _weakref__remove_dead_weakref(PyObject *module, PyObject *const *args, Py_ssize_ exit: return return_value; } -/*[clinic end generated code: output=eae22e2d2e43120e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c543dc2cd6ece975 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h index 5f45b7cf673473..33f82d4da8b6c9 100644 --- a/Modules/clinic/arraymodule.c.h +++ b/Modules/clinic/arraymodule.c.h @@ -345,7 +345,7 @@ array_array_fromstring(arrayobject *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("fromstring", 0, "contiguous buffer", arg); + _PyArg_BadArgument("fromstring", "argument", "contiguous buffer", arg); goto exit; } } @@ -382,7 +382,7 @@ array_array_frombytes(arrayobject *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("frombytes", 0, "contiguous buffer", arg); + _PyArg_BadArgument("frombytes", "argument", "contiguous buffer", arg); goto exit; } return_value = array_array_frombytes_impl(self, &buffer); @@ -537,14 +537,14 @@ array__array_reconstructor(PyObject *module, PyObject *const *args, Py_ssize_t n } arraytype = (PyTypeObject *)args[0]; if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("_array_reconstructor", 2, "a unicode character", args[1]); + _PyArg_BadArgument("_array_reconstructor", "argument 2", "a unicode character", args[1]); goto exit; } if (PyUnicode_READY(args[1])) { goto exit; } if (PyUnicode_GET_LENGTH(args[1]) != 1) { - _PyArg_BadArgument("_array_reconstructor", 2, "a unicode character", args[1]); + _PyArg_BadArgument("_array_reconstructor", "argument 2", "a unicode character", args[1]); goto exit; } typecode = PyUnicode_READ_CHAR(args[1], 0); @@ -599,4 +599,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=c9a40f11f1a866fb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6aa421571e2c0756 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/audioop.c.h b/Modules/clinic/audioop.c.h index 4ea7155373be62..8745533eeb629d 100644 --- a/Modules/clinic/audioop.c.h +++ b/Modules/clinic/audioop.c.h @@ -30,7 +30,7 @@ audioop_getsample(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("getsample", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("getsample", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -96,7 +96,7 @@ audioop_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("max", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("max", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -145,7 +145,7 @@ audioop_minmax(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("minmax", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("minmax", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -194,7 +194,7 @@ audioop_avg(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("avg", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("avg", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -243,7 +243,7 @@ audioop_rms(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("rms", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("rms", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -293,14 +293,14 @@ audioop_findfit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("findfit", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("findfit", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyObject_GetBuffer(args[1], &reference, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&reference, 'C')) { - _PyArg_BadArgument("findfit", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("findfit", "argument 2", "contiguous buffer", args[1]); goto exit; } return_value = audioop_findfit_impl(module, &fragment, &reference); @@ -345,14 +345,14 @@ audioop_findfactor(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("findfactor", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("findfactor", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyObject_GetBuffer(args[1], &reference, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&reference, 'C')) { - _PyArg_BadArgument("findfactor", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("findfactor", "argument 2", "contiguous buffer", args[1]); goto exit; } return_value = audioop_findfactor_impl(module, &fragment, &reference); @@ -397,7 +397,7 @@ audioop_findmax(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("findmax", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("findmax", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -454,7 +454,7 @@ audioop_avgpp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("avgpp", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("avgpp", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -503,7 +503,7 @@ audioop_maxpp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("maxpp", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("maxpp", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -552,7 +552,7 @@ audioop_cross(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("cross", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("cross", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -603,7 +603,7 @@ audioop_mul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("mul", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("mul", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -615,9 +615,15 @@ audioop_mul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - factor = PyFloat_AsDouble(args[2]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[2])) { + factor = PyFloat_AS_DOUBLE(args[2]); + } + else + { + factor = PyFloat_AsDouble(args[2]); + if (factor == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = audioop_mul_impl(module, &fragment, width, factor); @@ -659,7 +665,7 @@ audioop_tomono(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("tomono", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("tomono", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -671,13 +677,25 @@ audioop_tomono(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - lfactor = PyFloat_AsDouble(args[2]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[2])) { + lfactor = PyFloat_AS_DOUBLE(args[2]); } - rfactor = PyFloat_AsDouble(args[3]); - if (PyErr_Occurred()) { - goto exit; + else + { + lfactor = PyFloat_AsDouble(args[2]); + if (lfactor == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[3])) { + rfactor = PyFloat_AS_DOUBLE(args[3]); + } + else + { + rfactor = PyFloat_AsDouble(args[3]); + if (rfactor == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = audioop_tomono_impl(module, &fragment, width, lfactor, rfactor); @@ -719,7 +737,7 @@ audioop_tostereo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("tostereo", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("tostereo", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -731,13 +749,25 @@ audioop_tostereo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - lfactor = PyFloat_AsDouble(args[2]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[2])) { + lfactor = PyFloat_AS_DOUBLE(args[2]); } - rfactor = PyFloat_AsDouble(args[3]); - if (PyErr_Occurred()) { - goto exit; + else + { + lfactor = PyFloat_AsDouble(args[2]); + if (lfactor == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[3])) { + rfactor = PyFloat_AS_DOUBLE(args[3]); + } + else + { + rfactor = PyFloat_AsDouble(args[3]); + if (rfactor == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = audioop_tostereo_impl(module, &fragment, width, lfactor, rfactor); @@ -778,14 +808,14 @@ audioop_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment1, 'C')) { - _PyArg_BadArgument("add", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("add", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyObject_GetBuffer(args[1], &fragment2, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment2, 'C')) { - _PyArg_BadArgument("add", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("add", "argument 2", "contiguous buffer", args[1]); goto exit; } if (PyFloat_Check(args[2])) { @@ -839,7 +869,7 @@ audioop_bias(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("bias", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("bias", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -897,7 +927,7 @@ audioop_reverse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("reverse", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("reverse", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -946,7 +976,7 @@ audioop_byteswap(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("byteswap", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("byteswap", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -997,7 +1027,7 @@ audioop_lin2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("lin2lin", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("lin2lin", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -1064,7 +1094,7 @@ audioop_ratecv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("ratecv", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("ratecv", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -1166,7 +1196,7 @@ audioop_lin2ulaw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("lin2ulaw", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("lin2ulaw", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -1215,7 +1245,7 @@ audioop_ulaw2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("ulaw2lin", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("ulaw2lin", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -1264,7 +1294,7 @@ audioop_lin2alaw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("lin2alaw", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("lin2alaw", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -1313,7 +1343,7 @@ audioop_alaw2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("alaw2lin", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("alaw2lin", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -1364,7 +1394,7 @@ audioop_lin2adpcm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("lin2adpcm", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("lin2adpcm", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -1416,7 +1446,7 @@ audioop_adpcm2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { - _PyArg_BadArgument("adpcm2lin", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("adpcm2lin", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -1439,4 +1469,4 @@ audioop_adpcm2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -/*[clinic end generated code: output=2b173a25726252e9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6b4f2c597f295abc input=a9049054013a1b77]*/ diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h index d4850485690278..82942f08a68681 100644 --- a/Modules/clinic/binascii.c.h +++ b/Modules/clinic/binascii.c.h @@ -64,7 +64,7 @@ binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("b2a_uu", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("b2a_uu", "argument 1", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -153,7 +153,7 @@ binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("b2a_base64", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("b2a_base64", "argument 1", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -233,7 +233,7 @@ binascii_rlecode_hqx(PyObject *module, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("rlecode_hqx", 0, "contiguous buffer", arg); + _PyArg_BadArgument("rlecode_hqx", "argument", "contiguous buffer", arg); goto exit; } return_value = binascii_rlecode_hqx_impl(module, &data); @@ -269,7 +269,7 @@ binascii_b2a_hqx(PyObject *module, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("b2a_hqx", 0, "contiguous buffer", arg); + _PyArg_BadArgument("b2a_hqx", "argument", "contiguous buffer", arg); goto exit; } return_value = binascii_b2a_hqx_impl(module, &data); @@ -305,7 +305,7 @@ binascii_rledecode_hqx(PyObject *module, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("rledecode_hqx", 0, "contiguous buffer", arg); + _PyArg_BadArgument("rledecode_hqx", "argument", "contiguous buffer", arg); goto exit; } return_value = binascii_rledecode_hqx_impl(module, &data); @@ -346,7 +346,7 @@ binascii_crc_hqx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("crc_hqx", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("crc_hqx", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyFloat_Check(args[1])) { @@ -400,7 +400,7 @@ binascii_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("crc32", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("crc32", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -432,7 +432,7 @@ binascii_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } PyDoc_STRVAR(binascii_b2a_hex__doc__, -"b2a_hex($module, /, data, sep=None, bytes_per_sep=1)\n" +"b2a_hex($module, /, data, sep=, bytes_per_sep=1)\n" "--\n" "\n" "Hexadecimal representation of binary data.\n" @@ -481,7 +481,7 @@ binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("b2a_hex", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("b2a_hex", "argument 'data'", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -515,7 +515,7 @@ binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb } PyDoc_STRVAR(binascii_hexlify__doc__, -"hexlify($module, /, data, sep=None, bytes_per_sep=1)\n" +"hexlify($module, /, data, sep=, bytes_per_sep=1)\n" "--\n" "\n" "Hexadecimal representation of binary data.\n" @@ -556,7 +556,7 @@ binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("hexlify", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("hexlify", "argument 'data'", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -747,7 +747,7 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("b2a_qp", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("b2a_qp", "argument 'data'", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -801,4 +801,4 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj return return_value; } -/*[clinic end generated code: output=f7b8049edb130c63 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ec26d03c2007eaac input=a9049054013a1b77]*/ diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h index 83c498c2240677..81a8437c3a7d17 100644 --- a/Modules/clinic/cmathmodule.c.h +++ b/Modules/clinic/cmathmodule.c.h @@ -648,10 +648,10 @@ cmath_tanh(PyObject *module, PyObject *arg) } PyDoc_STRVAR(cmath_log__doc__, -"log($module, x, y_obj=None, /)\n" +"log($module, z, base=, /)\n" "--\n" "\n" -"The logarithm of z to the given base.\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."); @@ -766,13 +766,25 @@ cmath_rect(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("rect", nargs, 2, 2)) { goto exit; } - r = PyFloat_AsDouble(args[0]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[0])) { + r = PyFloat_AS_DOUBLE(args[0]); } - phi = PyFloat_AsDouble(args[1]); - if (PyErr_Occurred()) { - goto exit; + else + { + r = PyFloat_AsDouble(args[0]); + if (r == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[1])) { + phi = PyFloat_AS_DOUBLE(args[1]); + } + else + { + phi = PyFloat_AsDouble(args[1]); + if (phi == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = cmath_rect_impl(module, r, phi); @@ -922,17 +934,29 @@ cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec goto skip_optional_kwonly; } if (args[2]) { - rel_tol = PyFloat_AsDouble(args[2]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[2])) { + rel_tol = PyFloat_AS_DOUBLE(args[2]); + } + else + { + rel_tol = PyFloat_AsDouble(args[2]); + if (rel_tol == -1.0 && PyErr_Occurred()) { + goto exit; + } } if (!--noptargs) { goto skip_optional_kwonly; } } - abs_tol = PyFloat_AsDouble(args[3]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[3])) { + abs_tol = PyFloat_AS_DOUBLE(args[3]); + } + else + { + abs_tol = PyFloat_AsDouble(args[3]); + if (abs_tol == -1.0 && PyErr_Occurred()) { + goto exit; + } } skip_optional_kwonly: _return_value = cmath_isclose_impl(module, a, b, rel_tol, abs_tol); @@ -944,4 +968,4 @@ cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=c7afb866e593fa45 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3edc4484b10ae752 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/grpmodule.c.h b/Modules/clinic/grpmodule.c.h index ae99c50955f648..2e2690ad8d3f11 100644 --- a/Modules/clinic/grpmodule.c.h +++ b/Modules/clinic/grpmodule.c.h @@ -64,7 +64,7 @@ grp_getgrnam(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("getgrnam", 1, "str", args[0]); + _PyArg_BadArgument("getgrnam", "argument 'name'", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -97,4 +97,4 @@ grp_getgrall(PyObject *module, PyObject *Py_UNUSED(ignored)) { return grp_getgrall_impl(module); } -/*[clinic end generated code: output=2aa6c60873d41ee8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9b3f26779e4e1a52 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/itertoolsmodule.c.h b/Modules/clinic/itertoolsmodule.c.h index b43ce64af0dc43..20594b0fed4c34 100644 --- a/Modules/clinic/itertoolsmodule.c.h +++ b/Modules/clinic/itertoolsmodule.c.h @@ -66,7 +66,7 @@ itertools__grouper(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), &groupby_type)) { - _PyArg_BadArgument("_grouper", 1, (&groupby_type)->tp_name, PyTuple_GET_ITEM(args, 0)); + _PyArg_BadArgument("_grouper", "argument 1", (&groupby_type)->tp_name, PyTuple_GET_ITEM(args, 0)); goto exit; } parent = PyTuple_GET_ITEM(args, 0); @@ -104,7 +104,7 @@ itertools_teedataobject(PyTypeObject *type, PyObject *args, PyObject *kwargs) } it = PyTuple_GET_ITEM(args, 0); if (!PyList_Check(PyTuple_GET_ITEM(args, 1))) { - _PyArg_BadArgument("teedataobject", 2, "list", PyTuple_GET_ITEM(args, 1)); + _PyArg_BadArgument("teedataobject", "argument 2", "list", PyTuple_GET_ITEM(args, 1)); goto exit; } values = PyTuple_GET_ITEM(args, 1); @@ -642,4 +642,4 @@ itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=04c49debcae96003 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=392c9706e79f6710 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index cdf4305641b7d9..95d68ee55ae5ba 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -117,9 +117,15 @@ math_frexp(PyObject *module, PyObject *arg) PyObject *return_value = NULL; double x; - x = PyFloat_AsDouble(arg); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = math_frexp_impl(module, x); @@ -151,9 +157,15 @@ math_ldexp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("ldexp", nargs, 2, 2)) { goto exit; } - x = PyFloat_AsDouble(args[0]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[0])) { + x = PyFloat_AS_DOUBLE(args[0]); + } + else + { + x = PyFloat_AsDouble(args[0]); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } } i = args[1]; return_value = math_ldexp_impl(module, x, i); @@ -182,9 +194,15 @@ math_modf(PyObject *module, PyObject *arg) PyObject *return_value = NULL; double x; - x = PyFloat_AsDouble(arg); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = math_modf_impl(module, x); @@ -277,13 +295,25 @@ math_fmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("fmod", nargs, 2, 2)) { goto exit; } - x = PyFloat_AsDouble(args[0]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[0])) { + x = PyFloat_AS_DOUBLE(args[0]); } - y = PyFloat_AsDouble(args[1]); - if (PyErr_Occurred()) { - goto exit; + else + { + x = PyFloat_AsDouble(args[0]); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[1])) { + y = PyFloat_AS_DOUBLE(args[1]); + } + else + { + y = PyFloat_AsDouble(args[1]); + if (y == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = math_fmod_impl(module, x, y); @@ -297,8 +327,8 @@ PyDoc_STRVAR(math_dist__doc__, "\n" "Return the Euclidean distance between two points p and q.\n" "\n" -"The points should be specified as tuples of coordinates.\n" -"Both tuples must be the same size.\n" +"The points should be specified as sequences (or iterables) of\n" +"coordinates. Both inputs must have the same dimension.\n" "\n" "Roughly equivalent to:\n" " sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))"); @@ -319,15 +349,7 @@ math_dist(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("dist", nargs, 2, 2)) { goto exit; } - if (!PyTuple_Check(args[0])) { - _PyArg_BadArgument("dist", 1, "tuple", args[0]); - goto exit; - } p = args[0]; - if (!PyTuple_Check(args[1])) { - _PyArg_BadArgument("dist", 2, "tuple", args[1]); - goto exit; - } q = args[1]; return_value = math_dist_impl(module, p, q); @@ -357,13 +379,25 @@ math_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("pow", nargs, 2, 2)) { goto exit; } - x = PyFloat_AsDouble(args[0]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[0])) { + x = PyFloat_AS_DOUBLE(args[0]); } - y = PyFloat_AsDouble(args[1]); - if (PyErr_Occurred()) { - goto exit; + else + { + x = PyFloat_AsDouble(args[0]); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[1])) { + y = PyFloat_AS_DOUBLE(args[1]); + } + else + { + y = PyFloat_AsDouble(args[1]); + if (y == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = math_pow_impl(module, x, y); @@ -389,9 +423,15 @@ math_degrees(PyObject *module, PyObject *arg) PyObject *return_value = NULL; double x; - x = PyFloat_AsDouble(arg); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = math_degrees_impl(module, x); @@ -417,9 +457,15 @@ math_radians(PyObject *module, PyObject *arg) PyObject *return_value = NULL; double x; - x = PyFloat_AsDouble(arg); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = math_radians_impl(module, x); @@ -445,9 +491,15 @@ math_isfinite(PyObject *module, PyObject *arg) PyObject *return_value = NULL; double x; - x = PyFloat_AsDouble(arg); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = math_isfinite_impl(module, x); @@ -473,9 +525,15 @@ math_isnan(PyObject *module, PyObject *arg) PyObject *return_value = NULL; double x; - x = PyFloat_AsDouble(arg); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = math_isnan_impl(module, x); @@ -501,9 +559,15 @@ math_isinf(PyObject *module, PyObject *arg) PyObject *return_value = NULL; double x; - x = PyFloat_AsDouble(arg); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = math_isinf_impl(module, x); @@ -558,29 +622,53 @@ math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - a = PyFloat_AsDouble(args[0]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[0])) { + a = PyFloat_AS_DOUBLE(args[0]); } - b = PyFloat_AsDouble(args[1]); - if (PyErr_Occurred()) { - goto exit; + else + { + a = PyFloat_AsDouble(args[0]); + if (a == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[1])) { + b = PyFloat_AS_DOUBLE(args[1]); + } + else + { + b = PyFloat_AsDouble(args[1]); + if (b == -1.0 && PyErr_Occurred()) { + goto exit; + } } if (!noptargs) { goto skip_optional_kwonly; } if (args[2]) { - rel_tol = PyFloat_AsDouble(args[2]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[2])) { + rel_tol = PyFloat_AS_DOUBLE(args[2]); + } + else + { + rel_tol = PyFloat_AsDouble(args[2]); + if (rel_tol == -1.0 && PyErr_Occurred()) { + goto exit; + } } if (!--noptargs) { goto skip_optional_kwonly; } } - abs_tol = PyFloat_AsDouble(args[3]); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(args[3])) { + abs_tol = PyFloat_AS_DOUBLE(args[3]); + } + else + { + abs_tol = PyFloat_AsDouble(args[3]); + if (abs_tol == -1.0 && PyErr_Occurred()) { + goto exit; + } } skip_optional_kwonly: _return_value = math_isclose_impl(module, a, b, rel_tol, abs_tol); @@ -639,7 +727,7 @@ math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k } PyDoc_STRVAR(math_perm__doc__, -"perm($module, n, k, /)\n" +"perm($module, n, k=None, /)\n" "--\n" "\n" "Number of ways to choose k items from n items without repetition and with order.\n" @@ -647,6 +735,9 @@ PyDoc_STRVAR(math_perm__doc__, "Evaluates to n! / (n - k)! when k <= n and evaluates\n" "to zero when k > n.\n" "\n" +"If k is not specified or is None, then k defaults to n\n" +"and the function returns n!.\n" +"\n" "Raises TypeError if either of the arguments are not integers.\n" "Raises ValueError if either of the arguments are negative."); @@ -661,13 +752,17 @@ math_perm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; PyObject *n; - PyObject *k; + PyObject *k = Py_None; - if (!_PyArg_CheckPositional("perm", nargs, 2, 2)) { + if (!_PyArg_CheckPositional("perm", nargs, 1, 2)) { goto exit; } n = args[0]; + if (nargs < 2) { + goto skip_optional; + } k = args[1]; +skip_optional: return_value = math_perm_impl(module, n, k); exit: @@ -713,4 +808,4 @@ math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=5004266613284dcc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9a2b3dc91eb9aadd input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 22cb94761de5c7..c0d1d4df7957f6 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -616,7 +616,7 @@ os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * goto exit; } if (!PyLong_Check(args[1])) { - _PyArg_BadArgument("chflags", 2, "int", args[1]); + _PyArg_BadArgument("chflags", "argument 'flags'", "int", args[1]); goto exit; } flags = PyLong_AsUnsignedLongMask(args[1]); @@ -674,7 +674,7 @@ os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } if (!PyLong_Check(args[1])) { - _PyArg_BadArgument("lchflags", 2, "int", args[1]); + _PyArg_BadArgument("lchflags", "argument 'flags'", "int", args[1]); goto exit; } flags = PyLong_AsUnsignedLongMask(args[1]); @@ -1272,19 +1272,6 @@ os__getfinalpathname(PyObject *module, PyObject *arg) #if defined(MS_WINDOWS) -PyDoc_STRVAR(os__isdir__doc__, -"_isdir($module, path, /)\n" -"--\n" -"\n" -"Return true if the pathname refers to an existing directory."); - -#define OS__ISDIR_METHODDEF \ - {"_isdir", (PyCFunction)os__isdir, METH_O, os__isdir__doc__}, - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - PyDoc_STRVAR(os__getvolumepathname__doc__, "_getvolumepathname($module, /, path)\n" "--\n" @@ -1984,8 +1971,8 @@ os_uname(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* defined(HAVE_UNAME) */ PyDoc_STRVAR(os_utime__doc__, -"utime($module, /, path, times=None, *, ns=None, dir_fd=None,\n" -" follow_symlinks=True)\n" +"utime($module, /, path, times=None, *, ns=,\n" +" dir_fd=None, follow_symlinks=True)\n" "--\n" "\n" "Set the access and modified time of path.\n" @@ -2028,7 +2015,7 @@ os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw 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); - PyObject *times = NULL; + PyObject *times = Py_None; PyObject *ns = NULL; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; @@ -2221,8 +2208,8 @@ os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k PyDoc_STRVAR(os_posix_spawn__doc__, "posix_spawn($module, path, argv, env, /, *, file_actions=(),\n" -" setpgroup=None, resetids=False, setsid=False,\n" -" setsigmask=(), setsigdef=(), scheduler=None)\n" +" setpgroup=, resetids=False, setsid=False,\n" +" setsigmask=(), setsigdef=(), scheduler=)\n" "--\n" "\n" "Execute the program specified by path in a new process.\n" @@ -2358,8 +2345,8 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje PyDoc_STRVAR(os_posix_spawnp__doc__, "posix_spawnp($module, path, argv, env, /, *, file_actions=(),\n" -" setpgroup=None, resetids=False, setsid=False,\n" -" setsigmask=(), setsigdef=(), scheduler=None)\n" +" setpgroup=, resetids=False, setsid=False,\n" +" setsigmask=(), setsigdef=(), scheduler=)\n" "--\n" "\n" "Execute the program specified by path in a new process.\n" @@ -2611,8 +2598,9 @@ os_spawnve(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #if defined(HAVE_FORK) PyDoc_STRVAR(os_register_at_fork__doc__, -"register_at_fork($module, /, *, before=None, after_in_child=None,\n" -" after_in_parent=None)\n" +"register_at_fork($module, /, *, before=,\n" +" after_in_child=,\n" +" after_in_parent=)\n" "--\n" "\n" "Register callables to be called when forking a new process.\n" @@ -4969,7 +4957,7 @@ os_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("write", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("write", "argument 2", "contiguous buffer", args[1]); goto exit; } _return_value = os_write_impl(module, fd, &data); @@ -5292,7 +5280,7 @@ os_pwrite(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("pwrite", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("pwrite", "argument 2", "contiguous buffer", args[1]); goto exit; } if (!Py_off_t_converter(args[2], &offset)) { @@ -6025,7 +6013,7 @@ os_putenv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("putenv", 1, "str", args[0]); + _PyArg_BadArgument("putenv", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -6033,7 +6021,7 @@ os_putenv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } name = args[0]; if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("putenv", 2, "str", args[1]); + _PyArg_BadArgument("putenv", "argument 2", "str", args[1]); goto exit; } if (PyUnicode_READY(args[1]) == -1) { @@ -6867,11 +6855,9 @@ os_abort(PyObject *module, PyObject *Py_UNUSED(ignored)) #if defined(MS_WINDOWS) PyDoc_STRVAR(os_startfile__doc__, -"startfile($module, /, filepath, operation=None)\n" +"startfile($module, /, filepath, operation=)\n" "--\n" "\n" -"startfile(filepath [, operation])\n" -"\n" "Start a file with its associated application.\n" "\n" "When \"operation\" is not specified or \"open\", this acts like\n" @@ -7229,7 +7215,7 @@ os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } if (!PyBuffer_IsContiguous(&value, 'C')) { - _PyArg_BadArgument("setxattr", 3, "contiguous buffer", args[2]); + _PyArg_BadArgument("setxattr", "argument 'value'", "contiguous buffer", args[2]); goto exit; } if (!noptargs) { @@ -8274,10 +8260,6 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #define OS__GETFINALPATHNAME_METHODDEF #endif /* !defined(OS__GETFINALPATHNAME_METHODDEF) */ -#ifndef OS__ISDIR_METHODDEF - #define OS__ISDIR_METHODDEF -#endif /* !defined(OS__ISDIR_METHODDEF) */ - #ifndef OS__GETVOLUMEPATHNAME_METHODDEF #define OS__GETVOLUMEPATHNAME_METHODDEF #endif /* !defined(OS__GETVOLUMEPATHNAME_METHODDEF) */ @@ -8741,4 +8723,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=b3ae8afd275ea5cd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1ded1fbc8fd37b27 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pwdmodule.c.h b/Modules/clinic/pwdmodule.c.h index cf84ec959d58cc..cb83062495dcf9 100644 --- a/Modules/clinic/pwdmodule.c.h +++ b/Modules/clinic/pwdmodule.c.h @@ -34,7 +34,7 @@ pwd_getpwnam(PyObject *module, PyObject *arg) PyObject *name; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("getpwnam", 0, "str", arg); + _PyArg_BadArgument("getpwnam", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -74,4 +74,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=f9412bdedc69706c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7fceab7f1a85da36 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pyexpat.c.h b/Modules/clinic/pyexpat.c.h index dfb27d5f111418..ee5907ca7e447b 100644 --- a/Modules/clinic/pyexpat.c.h +++ b/Modules/clinic/pyexpat.c.h @@ -75,7 +75,7 @@ pyexpat_xmlparser_SetBase(xmlparseobject *self, PyObject *arg) const char *base; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("SetBase", 0, "str", arg); + _PyArg_BadArgument("SetBase", "argument", "str", arg); goto exit; } Py_ssize_t base_length; @@ -133,7 +133,8 @@ pyexpat_xmlparser_GetInputContext(xmlparseobject *self, PyObject *Py_UNUSED(igno } PyDoc_STRVAR(pyexpat_xmlparser_ExternalEntityParserCreate__doc__, -"ExternalEntityParserCreate($self, context, encoding=None, /)\n" +"ExternalEntityParserCreate($self, context, encoding=,\n" +" /)\n" "--\n" "\n" "Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler."); @@ -171,14 +172,14 @@ pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyObject *con } } else { - _PyArg_BadArgument("ExternalEntityParserCreate", 1, "str or None", args[0]); + _PyArg_BadArgument("ExternalEntityParserCreate", "argument 1", "str or None", args[0]); goto exit; } if (nargs < 2) { goto skip_optional; } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("ExternalEntityParserCreate", 2, "str", args[1]); + _PyArg_BadArgument("ExternalEntityParserCreate", "argument 2", "str", args[1]); goto exit; } Py_ssize_t encoding_length; @@ -280,7 +281,7 @@ pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyObject *const *args, Py_ PyDoc_STRVAR(pyexpat_ParserCreate__doc__, "ParserCreate($module, /, encoding=None, namespace_separator=None,\n" -" intern=None)\n" +" intern=)\n" "--\n" "\n" "Return a new XML parser object."); @@ -327,7 +328,7 @@ pyexpat_ParserCreate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, } } else { - _PyArg_BadArgument("ParserCreate", 1, "str or None", args[0]); + _PyArg_BadArgument("ParserCreate", "argument 'encoding'", "str or None", args[0]); goto exit; } if (!--noptargs) { @@ -350,7 +351,7 @@ pyexpat_ParserCreate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, } } else { - _PyArg_BadArgument("ParserCreate", 2, "str or None", args[1]); + _PyArg_BadArgument("ParserCreate", "argument 'namespace_separator'", "str or None", args[1]); goto exit; } if (!--noptargs) { @@ -401,4 +402,4 @@ pyexpat_ErrorString(PyObject *module, PyObject *arg) #ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */ -/*[clinic end generated code: output=e48f37d326956bdd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=68ce25024280af41 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index bc46515cb436bd..3cb1db14878c56 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -590,7 +590,7 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyLong_Check(args[0])) { - _PyArg_BadArgument("pthread_kill", 1, "int", args[0]); + _PyArg_BadArgument("pthread_kill", "argument 1", "int", args[0]); goto exit; } thread_id = PyLong_AsUnsignedLongMask(args[0]); @@ -658,4 +658,4 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #ifndef SIGNAL_PTHREAD_KILL_METHODDEF #define SIGNAL_PTHREAD_KILL_METHODDEF #endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */ -/*[clinic end generated code: output=f0d3a5703581da76 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3320b8f73c20ba60 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/spwdmodule.c.h b/Modules/clinic/spwdmodule.c.h index e051e6eb658992..411d2344e18fba 100644 --- a/Modules/clinic/spwdmodule.c.h +++ b/Modules/clinic/spwdmodule.c.h @@ -25,7 +25,7 @@ spwd_getspnam(PyObject *module, PyObject *arg_) PyObject *arg; if (!PyUnicode_Check(arg_)) { - _PyArg_BadArgument("getspnam", 0, "str", arg_); + _PyArg_BadArgument("getspnam", "argument", "str", arg_); goto exit; } if (PyUnicode_READY(arg_) == -1) { @@ -71,4 +71,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=2bbaa6bab1d9116e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=eec8d0bedcd312e5 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/symtablemodule.c.h b/Modules/clinic/symtablemodule.c.h index 7d8b0ad300c2cf..4a17f130ac97bc 100644 --- a/Modules/clinic/symtablemodule.c.h +++ b/Modules/clinic/symtablemodule.c.h @@ -31,7 +31,7 @@ _symtable_symtable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[2])) { - _PyArg_BadArgument("symtable", 3, "str", args[2]); + _PyArg_BadArgument("symtable", "argument 3", "str", args[2]); goto exit; } Py_ssize_t startstr_length; @@ -48,4 +48,4 @@ _symtable_symtable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=de655625eee705f4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a12f75cdbdf4e52a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/unicodedata.c.h b/Modules/clinic/unicodedata.c.h index 8ca0881efcf8b2..4251db2edc7b96 100644 --- a/Modules/clinic/unicodedata.c.h +++ b/Modules/clinic/unicodedata.c.h @@ -3,7 +3,7 @@ preserve [clinic start generated code]*/ PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, -"decimal($self, chr, default=None, /)\n" +"decimal($self, chr, default=, /)\n" "--\n" "\n" "Converts a Unicode character into its equivalent decimal value.\n" @@ -30,14 +30,14 @@ unicodedata_UCD_decimal(PyObject *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("decimal", 1, "a unicode character", args[0]); + _PyArg_BadArgument("decimal", "argument 1", "a unicode character", args[0]); goto exit; } if (PyUnicode_READY(args[0])) { goto exit; } if (PyUnicode_GET_LENGTH(args[0]) != 1) { - _PyArg_BadArgument("decimal", 1, "a unicode character", args[0]); + _PyArg_BadArgument("decimal", "argument 1", "a unicode character", args[0]); goto exit; } chr = PyUnicode_READ_CHAR(args[0], 0); @@ -53,7 +53,7 @@ unicodedata_UCD_decimal(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } PyDoc_STRVAR(unicodedata_UCD_digit__doc__, -"digit($self, chr, default=None, /)\n" +"digit($self, chr, default=, /)\n" "--\n" "\n" "Converts a Unicode character into its equivalent digit value.\n" @@ -79,14 +79,14 @@ unicodedata_UCD_digit(PyObject *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("digit", 1, "a unicode character", args[0]); + _PyArg_BadArgument("digit", "argument 1", "a unicode character", args[0]); goto exit; } if (PyUnicode_READY(args[0])) { goto exit; } if (PyUnicode_GET_LENGTH(args[0]) != 1) { - _PyArg_BadArgument("digit", 1, "a unicode character", args[0]); + _PyArg_BadArgument("digit", "argument 1", "a unicode character", args[0]); goto exit; } chr = PyUnicode_READ_CHAR(args[0], 0); @@ -102,7 +102,7 @@ unicodedata_UCD_digit(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } PyDoc_STRVAR(unicodedata_UCD_numeric__doc__, -"numeric($self, chr, default=None, /)\n" +"numeric($self, chr, default=, /)\n" "--\n" "\n" "Converts a Unicode character into its equivalent numeric value.\n" @@ -129,14 +129,14 @@ unicodedata_UCD_numeric(PyObject *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("numeric", 1, "a unicode character", args[0]); + _PyArg_BadArgument("numeric", "argument 1", "a unicode character", args[0]); goto exit; } if (PyUnicode_READY(args[0])) { goto exit; } if (PyUnicode_GET_LENGTH(args[0]) != 1) { - _PyArg_BadArgument("numeric", 1, "a unicode character", args[0]); + _PyArg_BadArgument("numeric", "argument 1", "a unicode character", args[0]); goto exit; } chr = PyUnicode_READ_CHAR(args[0], 0); @@ -170,14 +170,14 @@ unicodedata_UCD_category(PyObject *self, PyObject *arg) int chr; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("category", 0, "a unicode character", arg); + _PyArg_BadArgument("category", "argument", "a unicode character", arg); goto exit; } if (PyUnicode_READY(arg)) { goto exit; } if (PyUnicode_GET_LENGTH(arg) != 1) { - _PyArg_BadArgument("category", 0, "a unicode character", arg); + _PyArg_BadArgument("category", "argument", "a unicode character", arg); goto exit; } chr = PyUnicode_READ_CHAR(arg, 0); @@ -208,14 +208,14 @@ unicodedata_UCD_bidirectional(PyObject *self, PyObject *arg) int chr; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("bidirectional", 0, "a unicode character", arg); + _PyArg_BadArgument("bidirectional", "argument", "a unicode character", arg); goto exit; } if (PyUnicode_READY(arg)) { goto exit; } if (PyUnicode_GET_LENGTH(arg) != 1) { - _PyArg_BadArgument("bidirectional", 0, "a unicode character", arg); + _PyArg_BadArgument("bidirectional", "argument", "a unicode character", arg); goto exit; } chr = PyUnicode_READ_CHAR(arg, 0); @@ -247,14 +247,14 @@ unicodedata_UCD_combining(PyObject *self, PyObject *arg) int _return_value; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("combining", 0, "a unicode character", arg); + _PyArg_BadArgument("combining", "argument", "a unicode character", arg); goto exit; } if (PyUnicode_READY(arg)) { goto exit; } if (PyUnicode_GET_LENGTH(arg) != 1) { - _PyArg_BadArgument("combining", 0, "a unicode character", arg); + _PyArg_BadArgument("combining", "argument", "a unicode character", arg); goto exit; } chr = PyUnicode_READ_CHAR(arg, 0); @@ -291,14 +291,14 @@ unicodedata_UCD_mirrored(PyObject *self, PyObject *arg) int _return_value; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("mirrored", 0, "a unicode character", arg); + _PyArg_BadArgument("mirrored", "argument", "a unicode character", arg); goto exit; } if (PyUnicode_READY(arg)) { goto exit; } if (PyUnicode_GET_LENGTH(arg) != 1) { - _PyArg_BadArgument("mirrored", 0, "a unicode character", arg); + _PyArg_BadArgument("mirrored", "argument", "a unicode character", arg); goto exit; } chr = PyUnicode_READ_CHAR(arg, 0); @@ -331,14 +331,14 @@ unicodedata_UCD_east_asian_width(PyObject *self, PyObject *arg) int chr; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("east_asian_width", 0, "a unicode character", arg); + _PyArg_BadArgument("east_asian_width", "argument", "a unicode character", arg); goto exit; } if (PyUnicode_READY(arg)) { goto exit; } if (PyUnicode_GET_LENGTH(arg) != 1) { - _PyArg_BadArgument("east_asian_width", 0, "a unicode character", arg); + _PyArg_BadArgument("east_asian_width", "argument", "a unicode character", arg); goto exit; } chr = PyUnicode_READ_CHAR(arg, 0); @@ -369,14 +369,14 @@ unicodedata_UCD_decomposition(PyObject *self, PyObject *arg) int chr; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("decomposition", 0, "a unicode character", arg); + _PyArg_BadArgument("decomposition", "argument", "a unicode character", arg); goto exit; } if (PyUnicode_READY(arg)) { goto exit; } if (PyUnicode_GET_LENGTH(arg) != 1) { - _PyArg_BadArgument("decomposition", 0, "a unicode character", arg); + _PyArg_BadArgument("decomposition", "argument", "a unicode character", arg); goto exit; } chr = PyUnicode_READ_CHAR(arg, 0); @@ -412,7 +412,7 @@ unicodedata_UCD_is_normalized(PyObject *self, PyObject *const *args, Py_ssize_t goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("is_normalized", 1, "str", args[0]); + _PyArg_BadArgument("is_normalized", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -420,7 +420,7 @@ unicodedata_UCD_is_normalized(PyObject *self, PyObject *const *args, Py_ssize_t } form = args[0]; if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("is_normalized", 2, "str", args[1]); + _PyArg_BadArgument("is_normalized", "argument 2", "str", args[1]); goto exit; } if (PyUnicode_READY(args[1]) == -1) { @@ -459,7 +459,7 @@ unicodedata_UCD_normalize(PyObject *self, PyObject *const *args, Py_ssize_t narg goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("normalize", 1, "str", args[0]); + _PyArg_BadArgument("normalize", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -467,7 +467,7 @@ unicodedata_UCD_normalize(PyObject *self, PyObject *const *args, Py_ssize_t narg } form = args[0]; if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("normalize", 2, "str", args[1]); + _PyArg_BadArgument("normalize", "argument 2", "str", args[1]); goto exit; } if (PyUnicode_READY(args[1]) == -1) { @@ -481,7 +481,7 @@ unicodedata_UCD_normalize(PyObject *self, PyObject *const *args, Py_ssize_t narg } PyDoc_STRVAR(unicodedata_UCD_name__doc__, -"name($self, chr, default=None, /)\n" +"name($self, chr, default=, /)\n" "--\n" "\n" "Returns the name assigned to the character chr as a string.\n" @@ -506,14 +506,14 @@ unicodedata_UCD_name(PyObject *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("name", 1, "a unicode character", args[0]); + _PyArg_BadArgument("name", "argument 1", "a unicode character", args[0]); goto exit; } if (PyUnicode_READY(args[0])) { goto exit; } if (PyUnicode_GET_LENGTH(args[0]) != 1) { - _PyArg_BadArgument("name", 1, "a unicode character", args[0]); + _PyArg_BadArgument("name", "argument 1", "a unicode character", args[0]); goto exit; } chr = PyUnicode_READ_CHAR(args[0], 0); @@ -559,4 +559,4 @@ unicodedata_UCD_lookup(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=0fc850fe5b6b312c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=10c23477dbe8a202 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zipimport.c.h b/Modules/clinic/zipimport.c.h deleted file mode 100644 index aabe7a05ae9dd6..00000000000000 --- a/Modules/clinic/zipimport.c.h +++ /dev/null @@ -1,325 +0,0 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(zipimport_zipimporter___init____doc__, -"zipimporter(archivepath, /)\n" -"--\n" -"\n" -"Create a new zipimporter instance.\n" -"\n" -" archivepath\n" -" A path-like object to a zipfile, or to a specific path inside\n" -" a zipfile.\n" -"\n" -"\'archivepath\' must be a path-like object to a zipfile, or to a specific path\n" -"inside a zipfile. For example, it can be \'/tmp/myimport.zip\', or\n" -"\'/tmp/myimport.zip/mydirectory\', if mydirectory is a valid directory inside\n" -"the archive.\n" -"\n" -"\'ZipImportError\' is raised if \'archivepath\' doesn\'t point to a valid Zip\n" -"archive.\n" -"\n" -"The \'archive\' attribute of the zipimporter object contains the name of the\n" -"zipfile targeted."); - -static int -zipimport_zipimporter___init___impl(ZipImporter *self, PyObject *path); - -static int -zipimport_zipimporter___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - PyObject *path; - - if ((Py_TYPE(self) == &ZipImporter_Type) && - !_PyArg_NoKeywords("zipimporter", kwargs)) { - goto exit; - } - if (!PyArg_ParseTuple(args, "O&:zipimporter", - PyUnicode_FSDecoder, &path)) { - goto exit; - } - return_value = zipimport_zipimporter___init___impl((ZipImporter *)self, path); - -exit: - return return_value; -} - -PyDoc_STRVAR(zipimport_zipimporter_find_module__doc__, -"find_module($self, fullname, path=None, /)\n" -"--\n" -"\n" -"Search for a module specified by \'fullname\'.\n" -"\n" -"\'fullname\' must be the fully qualified (dotted) module name. It returns the\n" -"zipimporter instance itself if the module was found, or None if it wasn\'t.\n" -"The optional \'path\' argument is ignored -- it\'s there for compatibility\n" -"with the importer protocol."); - -#define ZIPIMPORT_ZIPIMPORTER_FIND_MODULE_METHODDEF \ - {"find_module", (PyCFunction)(void *)zipimport_zipimporter_find_module, METH_FASTCALL, zipimport_zipimporter_find_module__doc__}, - -static PyObject * -zipimport_zipimporter_find_module_impl(ZipImporter *self, PyObject *fullname, - PyObject *path); - -static PyObject * -zipimport_zipimporter_find_module(ZipImporter *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *fullname; - PyObject *path = Py_None; - - if (!_PyArg_ParseStack(args, nargs, "U|O:find_module", - &fullname, &path)) { - goto exit; - } - return_value = zipimport_zipimporter_find_module_impl(self, fullname, path); - -exit: - return return_value; -} - -PyDoc_STRVAR(zipimport_zipimporter_find_loader__doc__, -"find_loader($self, fullname, path=None, /)\n" -"--\n" -"\n" -"Search for a module specified by \'fullname\'.\n" -"\n" -"\'fullname\' must be the fully qualified (dotted) module name. It returns the\n" -"zipimporter instance itself if the module was found, a string containing the\n" -"full path name if it\'s possibly a portion of a namespace package,\n" -"or None otherwise. The optional \'path\' argument is ignored -- it\'s\n" -"there for compatibility with the importer protocol."); - -#define ZIPIMPORT_ZIPIMPORTER_FIND_LOADER_METHODDEF \ - {"find_loader", (PyCFunction)(void *)zipimport_zipimporter_find_loader, METH_FASTCALL, zipimport_zipimporter_find_loader__doc__}, - -static PyObject * -zipimport_zipimporter_find_loader_impl(ZipImporter *self, PyObject *fullname, - PyObject *path); - -static PyObject * -zipimport_zipimporter_find_loader(ZipImporter *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *fullname; - PyObject *path = Py_None; - - if (!_PyArg_ParseStack(args, nargs, "U|O:find_loader", - &fullname, &path)) { - goto exit; - } - return_value = zipimport_zipimporter_find_loader_impl(self, fullname, path); - -exit: - return return_value; -} - -PyDoc_STRVAR(zipimport_zipimporter_load_module__doc__, -"load_module($self, fullname, /)\n" -"--\n" -"\n" -"Load the module specified by \'fullname\'.\n" -"\n" -"\'fullname\' must be the fully qualified (dotted) module name. It returns the\n" -"imported module, or raises ZipImportError if it wasn\'t found."); - -#define ZIPIMPORT_ZIPIMPORTER_LOAD_MODULE_METHODDEF \ - {"load_module", (PyCFunction)zipimport_zipimporter_load_module, METH_O, zipimport_zipimporter_load_module__doc__}, - -static PyObject * -zipimport_zipimporter_load_module_impl(ZipImporter *self, PyObject *fullname); - -static PyObject * -zipimport_zipimporter_load_module(ZipImporter *self, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *fullname; - - if (!PyArg_Parse(arg, "U:load_module", &fullname)) { - goto exit; - } - return_value = zipimport_zipimporter_load_module_impl(self, fullname); - -exit: - return return_value; -} - -PyDoc_STRVAR(zipimport_zipimporter_get_filename__doc__, -"get_filename($self, fullname, /)\n" -"--\n" -"\n" -"Return the filename for the specified module."); - -#define ZIPIMPORT_ZIPIMPORTER_GET_FILENAME_METHODDEF \ - {"get_filename", (PyCFunction)zipimport_zipimporter_get_filename, METH_O, zipimport_zipimporter_get_filename__doc__}, - -static PyObject * -zipimport_zipimporter_get_filename_impl(ZipImporter *self, - PyObject *fullname); - -static PyObject * -zipimport_zipimporter_get_filename(ZipImporter *self, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *fullname; - - if (!PyArg_Parse(arg, "U:get_filename", &fullname)) { - goto exit; - } - return_value = zipimport_zipimporter_get_filename_impl(self, fullname); - -exit: - return return_value; -} - -PyDoc_STRVAR(zipimport_zipimporter_is_package__doc__, -"is_package($self, fullname, /)\n" -"--\n" -"\n" -"Return True if the module specified by fullname is a package.\n" -"\n" -"Raise ZipImportError if the module couldn\'t be found."); - -#define ZIPIMPORT_ZIPIMPORTER_IS_PACKAGE_METHODDEF \ - {"is_package", (PyCFunction)zipimport_zipimporter_is_package, METH_O, zipimport_zipimporter_is_package__doc__}, - -static PyObject * -zipimport_zipimporter_is_package_impl(ZipImporter *self, PyObject *fullname); - -static PyObject * -zipimport_zipimporter_is_package(ZipImporter *self, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *fullname; - - if (!PyArg_Parse(arg, "U:is_package", &fullname)) { - goto exit; - } - return_value = zipimport_zipimporter_is_package_impl(self, fullname); - -exit: - return return_value; -} - -PyDoc_STRVAR(zipimport_zipimporter_get_data__doc__, -"get_data($self, pathname, /)\n" -"--\n" -"\n" -"Return the data associated with \'pathname\'.\n" -"\n" -"Raise OSError if the file was not found."); - -#define ZIPIMPORT_ZIPIMPORTER_GET_DATA_METHODDEF \ - {"get_data", (PyCFunction)zipimport_zipimporter_get_data, METH_O, zipimport_zipimporter_get_data__doc__}, - -static PyObject * -zipimport_zipimporter_get_data_impl(ZipImporter *self, PyObject *path); - -static PyObject * -zipimport_zipimporter_get_data(ZipImporter *self, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *path; - - if (!PyArg_Parse(arg, "U:get_data", &path)) { - goto exit; - } - return_value = zipimport_zipimporter_get_data_impl(self, path); - -exit: - return return_value; -} - -PyDoc_STRVAR(zipimport_zipimporter_get_code__doc__, -"get_code($self, fullname, /)\n" -"--\n" -"\n" -"Return the code object for the specified module.\n" -"\n" -"Raise ZipImportError if the module couldn\'t be found."); - -#define ZIPIMPORT_ZIPIMPORTER_GET_CODE_METHODDEF \ - {"get_code", (PyCFunction)zipimport_zipimporter_get_code, METH_O, zipimport_zipimporter_get_code__doc__}, - -static PyObject * -zipimport_zipimporter_get_code_impl(ZipImporter *self, PyObject *fullname); - -static PyObject * -zipimport_zipimporter_get_code(ZipImporter *self, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *fullname; - - if (!PyArg_Parse(arg, "U:get_code", &fullname)) { - goto exit; - } - return_value = zipimport_zipimporter_get_code_impl(self, fullname); - -exit: - return return_value; -} - -PyDoc_STRVAR(zipimport_zipimporter_get_source__doc__, -"get_source($self, fullname, /)\n" -"--\n" -"\n" -"Return the source code for the specified module.\n" -"\n" -"Raise ZipImportError if the module couldn\'t be found, return None if the\n" -"archive does contain the module, but has no source for it."); - -#define ZIPIMPORT_ZIPIMPORTER_GET_SOURCE_METHODDEF \ - {"get_source", (PyCFunction)zipimport_zipimporter_get_source, METH_O, zipimport_zipimporter_get_source__doc__}, - -static PyObject * -zipimport_zipimporter_get_source_impl(ZipImporter *self, PyObject *fullname); - -static PyObject * -zipimport_zipimporter_get_source(ZipImporter *self, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *fullname; - - if (!PyArg_Parse(arg, "U:get_source", &fullname)) { - goto exit; - } - return_value = zipimport_zipimporter_get_source_impl(self, fullname); - -exit: - return return_value; -} - -PyDoc_STRVAR(zipimport_zipimporter_get_resource_reader__doc__, -"get_resource_reader($self, fullname, /)\n" -"--\n" -"\n" -"Return the ResourceReader for a package in a zip file.\n" -"\n" -"If \'fullname\' is a package within the zip file, return the \'ResourceReader\'\n" -"object for the package. Otherwise return None."); - -#define ZIPIMPORT_ZIPIMPORTER_GET_RESOURCE_READER_METHODDEF \ - {"get_resource_reader", (PyCFunction)zipimport_zipimporter_get_resource_reader, METH_O, zipimport_zipimporter_get_resource_reader__doc__}, - -static PyObject * -zipimport_zipimporter_get_resource_reader_impl(ZipImporter *self, - PyObject *fullname); - -static PyObject * -zipimport_zipimporter_get_resource_reader(ZipImporter *self, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *fullname; - - if (!PyArg_Parse(arg, "U:get_resource_reader", &fullname)) { - goto exit; - } - return_value = zipimport_zipimporter_get_resource_reader_impl(self, fullname); - -exit: - return return_value; -} -/*[clinic end generated code: output=854ce3502180dc1f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index aa579209108d85..77ea04a353bf14 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -38,7 +38,7 @@ zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("compress", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("compress", "argument 1", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -105,7 +105,7 @@ zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("decompress", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("decompress", "argument 1", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -273,7 +273,7 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto exit; } if (!PyBuffer_IsContiguous(&zdict, 'C')) { - _PyArg_BadArgument("compressobj", 6, "contiguous buffer", args[5]); + _PyArg_BadArgument("compressobj", "argument 'zdict'", "contiguous buffer", args[5]); goto exit; } skip_optional_pos: @@ -375,7 +375,7 @@ zlib_Compress_compress(compobject *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("compress", 0, "contiguous buffer", arg); + _PyArg_BadArgument("compress", "argument", "contiguous buffer", arg); goto exit; } return_value = zlib_Compress_compress_impl(self, &data); @@ -432,7 +432,7 @@ zlib_Decompress_decompress(compobject *self, PyObject *const *args, Py_ssize_t n goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("decompress", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("decompress", "argument 1", "contiguous buffer", args[0]); goto exit; } if (!noptargs) { @@ -677,7 +677,7 @@ zlib_adler32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("adler32", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("adler32", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -735,7 +735,7 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("crc32", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("crc32", "argument 1", "contiguous buffer", args[0]); goto exit; } if (nargs < 2) { @@ -785,4 +785,4 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */ -/*[clinic end generated code: output=feb079cebbbaacd6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=faae38ef96b88b16 input=a9049054013a1b77]*/ diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c index b421f04fa605c2..02c09bbea48ac3 100644 --- a/Modules/cmathmodule.c +++ b/Modules/cmathmodule.c @@ -944,18 +944,18 @@ cmath_tanh_impl(PyObject *module, Py_complex z) /*[clinic input] cmath.log - x: Py_complex - y_obj: object = NULL + z as x: Py_complex + base as y_obj: object = NULL / -The logarithm of z to the given base. +log(z[, base]) -> the logarithm of z to the given base. If the base not specified, 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=ee0e823a7c6e68ea]*/ +/*[clinic end generated code: output=4effdb7d258e0d94 input=230ed3a71ecd000a]*/ { Py_complex y; diff --git a/Modules/expat/asciitab.h b/Modules/expat/asciitab.h index 2f59fd92906537..63b1d1b4482efa 100644 --- a/Modules/expat/asciitab.h +++ b/Modules/expat/asciitab.h @@ -31,34 +31,34 @@ */ /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, -/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, -/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, -/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, -/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, -/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, -/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, -/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, -/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, -/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, -/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, -/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, -/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, -/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, -/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, -/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, -/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, -/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, + /* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, + /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, + /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, + /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, + /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, + /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, + /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, + /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, + /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, + /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, + /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, + /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, + /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, + /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, + /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, + /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, + /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index 174c3fafda3f27..6c8eb1fda4a30c 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -33,15 +33,6 @@ #ifndef Expat_INCLUDED #define Expat_INCLUDED 1 -#ifdef __VMS -/* 0 1 2 3 0 1 2 3 - 1234567890123456789012345678901 1234567890123456789012345678901 */ -#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler -#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler -#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler -#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg -#endif - #include #include "expat_external.h" @@ -53,8 +44,8 @@ struct XML_ParserStruct; typedef struct XML_ParserStruct *XML_Parser; typedef unsigned char XML_Bool; -#define XML_TRUE ((XML_Bool) 1) -#define XML_FALSE ((XML_Bool) 0) +#define XML_TRUE ((XML_Bool)1) +#define XML_FALSE ((XML_Bool)0) /* The XML_Status enum gives the possible return values for several API functions. The preprocessor #defines are included so this @@ -164,25 +155,23 @@ enum XML_Content_Quant { typedef struct XML_cp XML_Content; struct XML_cp { - enum XML_Content_Type type; - enum XML_Content_Quant quant; - XML_Char * name; - unsigned int numchildren; - XML_Content * children; + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char *name; + unsigned int numchildren; + XML_Content *children; }; - /* 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. */ -typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, - const XML_Char *name, - XML_Content *model); +typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, + const XML_Char *name, + XML_Content *model); XMLPARSEAPI(void) -XML_SetElementDeclHandler(XML_Parser parser, - XML_ElementDeclHandler eldecl); +XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl); /* The Attlist declaration handler is called for *each* attribute. So a single Attlist declaration with multiple attributes declared will @@ -192,17 +181,12 @@ XML_SetElementDeclHandler(XML_Parser parser, value will be NULL in the case of "#REQUIRED". If "isrequired" is true and default is non-NULL, then this is a "#FIXED" default. */ -typedef void (XMLCALL *XML_AttlistDeclHandler) ( - void *userData, - const XML_Char *elname, - const XML_Char *attname, - const XML_Char *att_type, - const XML_Char *dflt, - int isrequired); +typedef void(XMLCALL *XML_AttlistDeclHandler)( + void *userData, const XML_Char *elname, const XML_Char *attname, + const XML_Char *att_type, const XML_Char *dflt, int isrequired); XMLPARSEAPI(void) -XML_SetAttlistDeclHandler(XML_Parser parser, - XML_AttlistDeclHandler attdecl); +XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl); /* The XML declaration handler is called for *both* XML declarations and text declarations. The way to distinguish is that the version @@ -212,15 +196,13 @@ XML_SetAttlistDeclHandler(XML_Parser parser, was no standalone parameter in the declaration, that it was given as no, or that it was given as yes. */ -typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData, - const XML_Char *version, - const XML_Char *encoding, - int standalone); +typedef void(XMLCALL *XML_XmlDeclHandler)(void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); XMLPARSEAPI(void) -XML_SetXmlDeclHandler(XML_Parser parser, - XML_XmlDeclHandler xmldecl); - +XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler xmldecl); typedef struct { void *(*malloc_fcn)(size_t size); @@ -248,7 +230,6 @@ XML_ParserCreate(const XML_Char *encoding); XMLPARSEAPI(XML_Parser) XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); - /* Constructs a new parser using the memory management suite referred to by memsuite. If memsuite is NULL, then use the standard library memory suite. If namespaceSeparator is non-NULL it creates a parser with @@ -278,31 +259,27 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encoding); /* atts is array of name/value pairs, terminated by 0; names and values are 0 terminated. */ -typedef void (XMLCALL *XML_StartElementHandler) (void *userData, - const XML_Char *name, - const XML_Char **atts); - -typedef void (XMLCALL *XML_EndElementHandler) (void *userData, - const XML_Char *name); +typedef void(XMLCALL *XML_StartElementHandler)(void *userData, + const XML_Char *name, + const XML_Char **atts); +typedef void(XMLCALL *XML_EndElementHandler)(void *userData, + const XML_Char *name); /* s is not 0 terminated. */ -typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, - const XML_Char *s, - int len); +typedef void(XMLCALL *XML_CharacterDataHandler)(void *userData, + const XML_Char *s, int len); /* target and data are 0 terminated */ -typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( - void *userData, - const XML_Char *target, - const XML_Char *data); +typedef void(XMLCALL *XML_ProcessingInstructionHandler)(void *userData, + const XML_Char *target, + const XML_Char *data); /* data is 0 terminated */ -typedef void (XMLCALL *XML_CommentHandler) (void *userData, - const XML_Char *data); +typedef void(XMLCALL *XML_CommentHandler)(void *userData, const XML_Char *data); -typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); -typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); +typedef void(XMLCALL *XML_StartCdataSectionHandler)(void *userData); +typedef void(XMLCALL *XML_EndCdataSectionHandler)(void *userData); /* This is called for any characters in the XML document for which there is no applicable handler. This includes both characters that @@ -317,25 +294,23 @@ typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); default handler: for example, a comment might be split between multiple calls. */ -typedef void (XMLCALL *XML_DefaultHandler) (void *userData, - const XML_Char *s, - int len); +typedef void(XMLCALL *XML_DefaultHandler)(void *userData, const XML_Char *s, + int len); /* This is called for the start of the DOCTYPE declaration, before any DTD or internal subset is parsed. */ -typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( - void *userData, - const XML_Char *doctypeName, - const XML_Char *sysid, - const XML_Char *pubid, - int has_internal_subset); +typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); /* This is called for the start of the DOCTYPE declaration when the closing > is encountered, but after processing any external subset. */ -typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); +typedef void(XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); /* This is called for entity declarations. The is_parameter_entity argument will be non-zero if the entity is a parameter entity, zero @@ -355,20 +330,14 @@ typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); Note that is_parameter_entity can't be changed to XML_Bool, since that would break binary compatibility. */ -typedef void (XMLCALL *XML_EntityDeclHandler) ( - void *userData, - const XML_Char *entityName, - int is_parameter_entity, - const XML_Char *value, - int value_length, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName); +typedef void(XMLCALL *XML_EntityDeclHandler)( + void *userData, const XML_Char *entityName, int is_parameter_entity, + const XML_Char *value, int value_length, const XML_Char *base, + const XML_Char *systemId, const XML_Char *publicId, + const XML_Char *notationName); XMLPARSEAPI(void) -XML_SetEntityDeclHandler(XML_Parser parser, - XML_EntityDeclHandler handler); +XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler); /* OBSOLETE -- OBSOLETE -- OBSOLETE This handler has been superseded by the EntityDeclHandler above. @@ -379,24 +348,20 @@ XML_SetEntityDeclHandler(XML_Parser parser, entityName, systemId and notationName arguments will never be NULL. The other arguments may be. */ -typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( - void *userData, - const XML_Char *entityName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName); +typedef void(XMLCALL *XML_UnparsedEntityDeclHandler)( + void *userData, const XML_Char *entityName, const XML_Char *base, + const XML_Char *systemId, const XML_Char *publicId, + const XML_Char *notationName); /* This is called for a declaration of notation. The base argument is whatever was set by XML_SetBase. The notationName will never be NULL. The other arguments can be. */ -typedef void (XMLCALL *XML_NotationDeclHandler) ( - void *userData, - const XML_Char *notationName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId); +typedef void(XMLCALL *XML_NotationDeclHandler)(void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); /* When namespace processing is enabled, these are called once for each namespace declaration. The call to the start and end element @@ -404,14 +369,12 @@ typedef void (XMLCALL *XML_NotationDeclHandler) ( declaration handlers. For an xmlns attribute, prefix will be NULL. For an xmlns="" attribute, uri will be NULL. */ -typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( - void *userData, - const XML_Char *prefix, - const XML_Char *uri); +typedef void(XMLCALL *XML_StartNamespaceDeclHandler)(void *userData, + const XML_Char *prefix, + const XML_Char *uri); -typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( - void *userData, - const XML_Char *prefix); +typedef void(XMLCALL *XML_EndNamespaceDeclHandler)(void *userData, + const XML_Char *prefix); /* This is called if the document is not standalone, that is, it has an external subset or a reference to a parameter entity, but does not @@ -422,7 +385,7 @@ typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( conditions above this handler will only be called if the referenced entity was actually read. */ -typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); +typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData); /* This is called for a reference to an external parsed general entity. The referenced entity is not automatically parsed. The @@ -458,12 +421,11 @@ typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); Note that unlike other handlers the first argument is the parser, not userData. */ -typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( - XML_Parser parser, - const XML_Char *context, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId); +typedef int(XMLCALL *XML_ExternalEntityRefHandler)(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); /* This is called in two situations: 1) An entity reference is encountered for which no declaration @@ -475,10 +437,9 @@ typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( the event would be out of sync with the reporting of the declarations or attribute values */ -typedef void (XMLCALL *XML_SkippedEntityHandler) ( - void *userData, - const XML_Char *entityName, - int is_parameter_entity); +typedef void(XMLCALL *XML_SkippedEntityHandler)(void *userData, + const XML_Char *entityName, + int is_parameter_entity); /* This structure is filled in by the XML_UnknownEncodingHandler to provide information to the parser about encodings that are unknown @@ -535,8 +496,8 @@ typedef void (XMLCALL *XML_SkippedEntityHandler) ( typedef struct { int map[256]; void *data; - int (XMLCALL *convert)(void *data, const char *s); - void (XMLCALL *release)(void *data); + int(XMLCALL *convert)(void *data, const char *s); + void(XMLCALL *release)(void *data); } XML_Encoding; /* This is called for an encoding that is unknown to the parser. @@ -554,23 +515,19 @@ typedef struct { If info does not describe a suitable encoding, then the parser will return an XML_UNKNOWN_ENCODING error. */ -typedef int (XMLCALL *XML_UnknownEncodingHandler) ( - void *encodingHandlerData, - const XML_Char *name, - XML_Encoding *info); +typedef int(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); XMLPARSEAPI(void) -XML_SetElementHandler(XML_Parser parser, - XML_StartElementHandler start, +XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end); XMLPARSEAPI(void) -XML_SetStartElementHandler(XML_Parser parser, - XML_StartElementHandler handler); +XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler handler); XMLPARSEAPI(void) -XML_SetEndElementHandler(XML_Parser parser, - XML_EndElementHandler handler); +XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler handler); XMLPARSEAPI(void) XML_SetCharacterDataHandler(XML_Parser parser, @@ -580,8 +537,7 @@ XMLPARSEAPI(void) XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler handler); XMLPARSEAPI(void) -XML_SetCommentHandler(XML_Parser parser, - XML_CommentHandler handler); +XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler); XMLPARSEAPI(void) XML_SetCdataSectionHandler(XML_Parser parser, @@ -601,20 +557,17 @@ XML_SetEndCdataSectionHandler(XML_Parser parser, default handler, or to the skipped entity handler, if one is set. */ XMLPARSEAPI(void) -XML_SetDefaultHandler(XML_Parser parser, - XML_DefaultHandler handler); +XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler); /* This sets the default handler but does not inhibit expansion of internal entities. The entity reference will not be passed to the default handler. */ XMLPARSEAPI(void) -XML_SetDefaultHandlerExpand(XML_Parser parser, - XML_DefaultHandler handler); +XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler); XMLPARSEAPI(void) -XML_SetDoctypeDeclHandler(XML_Parser parser, - XML_StartDoctypeDeclHandler start, +XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, XML_EndDoctypeDeclHandler end); XMLPARSEAPI(void) @@ -622,16 +575,14 @@ XML_SetStartDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start); XMLPARSEAPI(void) -XML_SetEndDoctypeDeclHandler(XML_Parser parser, - XML_EndDoctypeDeclHandler end); +XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end); XMLPARSEAPI(void) XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler handler); XMLPARSEAPI(void) -XML_SetNotationDeclHandler(XML_Parser parser, - XML_NotationDeclHandler handler); +XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler); XMLPARSEAPI(void) XML_SetNamespaceDeclHandler(XML_Parser parser, @@ -659,8 +610,7 @@ XML_SetExternalEntityRefHandler(XML_Parser parser, instead of the parser object. */ XMLPARSEAPI(void) -XML_SetExternalEntityRefHandlerArg(XML_Parser parser, - void *arg); +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg); XMLPARSEAPI(void) XML_SetSkippedEntityHandler(XML_Parser parser, @@ -740,7 +690,6 @@ XML_UseParserAsHandlerArg(XML_Parser parser); XMLPARSEAPI(enum XML_Error) XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); - /* Sets the base to be used for resolving relative URIs in system identifiers in declarations. Resolving relative identifiers is left to the application: this value will be passed through as the @@ -780,10 +729,10 @@ XML_GetIdAttributeIndex(XML_Parser parser); info->valueEnd - info->valueStart = 4 bytes. */ typedef struct { - XML_Index nameStart; /* Offset to beginning of the attribute name. */ - XML_Index nameEnd; /* Offset after the attribute name's last byte. */ - XML_Index valueStart; /* Offset to beginning of the attribute value. */ - XML_Index valueEnd; /* Offset after the attribute value's last byte. */ + XML_Index nameStart; /* Offset to beginning of the attribute name. */ + XML_Index nameEnd; /* Offset after the attribute name's last byte. */ + XML_Index valueStart; /* Offset to beginning of the attribute value. */ + XML_Index valueEnd; /* Offset after the attribute value's last byte. */ } XML_AttrInfo; /* Returns an array of XML_AttrInfo structures for the attribute/value pairs @@ -819,20 +768,20 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal); (resumable = 0) an already suspended parser. Some call-backs may still follow because they would otherwise get lost. Examples: - endElementHandler() for empty elements when stopped in - startElementHandler(), - - endNameSpaceDeclHandler() when stopped in endElementHandler(), + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), and possibly others. Can be called from most handlers, including DTD related call-backs, except when parsing an external parameter entity and resumable != 0. Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. - Possible error codes: + Possible error codes: - XML_ERROR_SUSPENDED: when suspending an already suspended parser. - XML_ERROR_FINISHED: when the parser has already finished. - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. - When resumable != 0 (true) then parsing is suspended, that is, - XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. @@ -843,7 +792,7 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal); the externalEntityRefHandler() to call XML_StopParser() on the parent parser (recursively), if one wants to stop parsing altogether. - When suspended, parsing can be resumed by calling XML_ResumeParser(). + When suspended, parsing can be resumed by calling XML_ResumeParser(). */ XMLPARSEAPI(enum XML_Status) XML_StopParser(XML_Parser parser, XML_Bool resumable); @@ -851,7 +800,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable); /* Resumes parsing after it has been suspended with XML_StopParser(). Must not be called from within a handler call-back. Returns same status codes as XML_Parse() or XML_ParseBuffer(). - Additional error code XML_ERROR_NOT_SUSPENDED possible. + Additional error code XML_ERROR_NOT_SUSPENDED possible. *Note*: This must be called on the most deeply nested child parser instance @@ -863,12 +812,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable); XMLPARSEAPI(enum XML_Status) XML_ResumeParser(XML_Parser parser); -enum XML_Parsing { - XML_INITIALIZED, - XML_PARSING, - XML_FINISHED, - XML_SUSPENDED -}; +enum XML_Parsing { XML_INITIALIZED, XML_PARSING, XML_FINISHED, XML_SUSPENDED }; typedef struct { enum XML_Parsing parsing; @@ -900,8 +844,7 @@ XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); Otherwise returns a new XML_Parser object. */ XMLPARSEAPI(XML_Parser) -XML_ExternalEntityParserCreate(XML_Parser parser, - const XML_Char *context, +XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context, const XML_Char *encoding); enum XML_ParamEntityParsing { @@ -945,8 +888,7 @@ XML_SetParamEntityParsing(XML_Parser parser, Note: If parser == NULL, the function will do nothing and return 0. */ XMLPARSEAPI(int) -XML_SetHashSalt(XML_Parser parser, - unsigned long hash_salt); +XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt); /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then XML_GetErrorCode returns information about the error. @@ -963,7 +905,7 @@ XML_GetErrorCode(XML_Parser parser); be within the relevant markup. When called outside of the callback functions, the position indicated will be just past the last parse event (regardless of whether there was an associated callback). - + They may also be called after returning from a call to XML_Parse or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then the location is the location of the character at which the error @@ -995,14 +937,12 @@ XML_GetCurrentByteCount(XML_Parser parser); the handler that makes the call. */ XMLPARSEAPI(const char *) -XML_GetInputContext(XML_Parser parser, - int *offset, - int *size); +XML_GetInputContext(XML_Parser parser, int *offset, int *size); /* For backwards compatibility with previous versions. */ -#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber #define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber -#define XML_GetErrorByteIndex XML_GetCurrentByteIndex +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex /* Frees the content model passed to the element declaration handler */ XMLPARSEAPI(void) @@ -1062,21 +1002,20 @@ enum XML_FeatureEnum { }; typedef struct { - enum XML_FeatureEnum feature; - const XML_LChar *name; - long int value; + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; } XML_Feature; XMLPARSEAPI(const XML_Feature *) XML_GetFeatureList(void); - /* Expat follows the semantic versioning convention. See http://semver.org. */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 2 -#define XML_MICRO_VERSION 6 +#define XML_MICRO_VERSION 8 #ifdef __cplusplus } diff --git a/Modules/expat/expat_external.h b/Modules/expat/expat_external.h index 2d96b4f41ad703..f2b75dda8e2798 100644 --- a/Modules/expat/expat_external.h +++ b/Modules/expat/expat_external.h @@ -35,14 +35,6 @@ /* External API definitions */ -/* Namespace external symbols to allow multiple libexpat version to - co-exist. */ -#include "pyexpatns.h" - -#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) -# define XML_USE_MSC_EXTENSIONS 1 -#endif - /* Expat tries very hard to make the API boundary very specifically defined. There are two macros defined to control this boundary; each of these can be defined before including this header to @@ -65,12 +57,17 @@ compiled with the cdecl calling convention as the default since system headers may assume the cdecl convention. */ + +/* Namespace external symbols to allow multiple libexpat version to + co-exist. */ +#include "pyexpatns.h" + #ifndef XMLCALL -# if defined(_MSC_VER) -# define XMLCALL __cdecl -# elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER) -# define XMLCALL __attribute__((cdecl)) -# else +# if defined(_MSC_VER) +# define XMLCALL __cdecl +# elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER) +# define XMLCALL __attribute__((cdecl)) +# else /* For any platform which uses this definition and supports more than one calling convention, we need to extend this definition to declare the convention used on that platform, if it's possible to @@ -81,41 +78,46 @@ pre-processor and how to specify the same calling convention as the platform's malloc() implementation. */ -# define XMLCALL -# endif -#endif /* not defined XMLCALL */ - +# define XMLCALL +# endif +#endif /* not defined XMLCALL */ -#if !defined(XML_STATIC) && !defined(XMLIMPORT) -# ifndef XML_BUILDING_EXPAT +#if ! defined(XML_STATIC) && ! defined(XMLIMPORT) +# ifndef XML_BUILDING_EXPAT /* using Expat from an application */ -# ifdef XML_USE_MSC_EXTENSIONS -# define XMLIMPORT __declspec(dllimport) +# if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__) +# define XMLIMPORT __declspec(dllimport) +# endif + # endif +#endif /* not defined XML_STATIC */ -# endif -#endif /* not defined XML_STATIC */ +#ifndef XML_ENABLE_VISIBILITY +# define XML_ENABLE_VISIBILITY 0 +#endif -#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4) -# define XMLIMPORT __attribute__ ((visibility ("default"))) +#if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY +# define XMLIMPORT __attribute__((visibility("default"))) #endif /* If we didn't define it above, define it away: */ #ifndef XMLIMPORT -# define XMLIMPORT +# define XMLIMPORT #endif -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)) -# define XML_ATTR_MALLOC __attribute__((__malloc__)) +#if defined(__GNUC__) \ + && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)) +# define XML_ATTR_MALLOC __attribute__((__malloc__)) #else -# define XML_ATTR_MALLOC +# define XML_ATTR_MALLOC #endif -#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) -# define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) +#if defined(__GNUC__) \ + && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +# define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) #else -# define XML_ATTR_ALLOC_SIZE(x) +# define XML_ATTR_ALLOC_SIZE(x) #endif #define XMLPARSEAPI(type) XMLIMPORT type XMLCALL @@ -125,35 +127,30 @@ extern "C" { #endif #ifdef XML_UNICODE_WCHAR_T -# ifndef XML_UNICODE -# define XML_UNICODE -# endif -# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2) -# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc" -# endif +# ifndef XML_UNICODE +# define XML_UNICODE +# endif +# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2) +# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc" +# endif #endif -#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ -# ifdef XML_UNICODE_WCHAR_T +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +# ifdef XML_UNICODE_WCHAR_T typedef wchar_t XML_Char; typedef wchar_t XML_LChar; -# else +# else typedef unsigned short XML_Char; typedef char XML_LChar; -# endif /* XML_UNICODE_WCHAR_T */ -#else /* Information is UTF-8 encoded. */ +# endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ typedef char XML_Char; typedef char XML_LChar; -#endif /* XML_UNICODE */ +#endif /* XML_UNICODE */ -#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ -# if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 -typedef __int64 XML_Index; -typedef unsigned __int64 XML_Size; -# else +#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ typedef long long XML_Index; typedef unsigned long long XML_Size; -# endif #else typedef long XML_Index; typedef unsigned long XML_Size; diff --git a/Modules/expat/iasciitab.h b/Modules/expat/iasciitab.h index ce4a4bf7edef53..ea97cfcf678e06 100644 --- a/Modules/expat/iasciitab.h +++ b/Modules/expat/iasciitab.h @@ -32,34 +32,34 @@ /* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */ /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, -/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, -/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, -/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, -/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, -/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, -/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, -/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, -/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, -/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, -/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, -/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, -/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, -/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, -/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, -/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, -/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, -/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, + /* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, + /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, + /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, + /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, + /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, + /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, + /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, + /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, + /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, + /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, + /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, + /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, + /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, + /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, + /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, + /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, + /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/Modules/expat/internal.h b/Modules/expat/internal.h index e33fdcb0238d72..60913dab762f8f 100644 --- a/Modules/expat/internal.h +++ b/Modules/expat/internal.h @@ -49,7 +49,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__) +#if defined(__GNUC__) && defined(__i386__) && ! defined(__MINGW32__) /* We'll use this version by default only where we know it helps. regparm() generates warnings on Solaris boxes. See SF bug #692878. @@ -59,8 +59,8 @@ #define FASTCALL __attribute__((stdcall, regparm(3))) and let's try this: */ -#define FASTCALL __attribute__((regparm(3))) -#define PTRFASTCALL __attribute__((regparm(3))) +# define FASTCALL __attribute__((regparm(3))) +# define PTRFASTCALL __attribute__((regparm(3))) #endif /* Using __fastcall seems to have an unexpected negative effect under @@ -74,50 +74,49 @@ /* Make sure all of these are defined if they aren't already. */ #ifndef FASTCALL -#define FASTCALL +# define FASTCALL #endif #ifndef PTRCALL -#define PTRCALL +# define PTRCALL #endif #ifndef PTRFASTCALL -#define PTRFASTCALL +# define PTRFASTCALL #endif #ifndef XML_MIN_SIZE -#if !defined(__cplusplus) && !defined(inline) -#ifdef __GNUC__ -#define inline __inline -#endif /* __GNUC__ */ -#endif +# if ! defined(__cplusplus) && ! defined(inline) +# ifdef __GNUC__ +# define inline __inline +# endif /* __GNUC__ */ +# endif #endif /* XML_MIN_SIZE */ #ifdef __cplusplus -#define inline inline +# define inline inline #else -#ifndef inline -#define inline -#endif +# ifndef inline +# define inline +# endif #endif #ifndef UNUSED_P -# ifdef __GNUC__ -# define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__)) -# else -# define UNUSED_P(p) UNUSED_ ## p -# endif +# define UNUSED_P(p) (void)p #endif - #ifdef __cplusplus extern "C" { #endif - +#ifdef XML_ENABLE_VISIBILITY +# if XML_ENABLE_VISIBILITY +__attribute__((visibility("default"))) +# endif +#endif void -_INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** fromLimRef); - +_INTERNAL_trim_to_complete_utf8_characters(const char *from, + const char **fromLimRef); #ifdef __cplusplus } diff --git a/Modules/expat/latin1tab.h b/Modules/expat/latin1tab.h index 95dfa52b1fbebb..6f916041355a86 100644 --- a/Modules/expat/latin1tab.h +++ b/Modules/expat/latin1tab.h @@ -31,34 +31,34 @@ */ /* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, -/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, -/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, -/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, -/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, -/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, + /* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, + /* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, + /* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, + /* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, + /* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, diff --git a/Modules/expat/loadlibrary.c b/Modules/expat/loadlibrary.c deleted file mode 100644 index 35fdf98bce6cea..00000000000000 --- a/Modules/expat/loadlibrary.c +++ /dev/null @@ -1,143 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2016 - 2017, Steve Holme, . - * Copyright (C) 2017, Expat development team - * - * All rights reserved. - * Licensed under the MIT license: - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * 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 OF - * THIRD PARTY RIGHTS. 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. - * - * Except as contained in this notice, the name of a copyright holder shall - * not be used in advertising or otherwise to promote the sale, use or other - * dealings in this Software without prior written authorization of the - * copyright holder. - * - ***************************************************************************/ - -#if defined(_WIN32) - -#include -#include - - -HMODULE _Expat_LoadLibrary(LPCTSTR filename); - - -#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH) -#define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 -#endif - -#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32) -#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 -#endif - -/* We use our own typedef here since some headers might lack these */ -typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD); - -/* See function definitions in winbase.h */ -#ifdef UNICODE -# ifdef _WIN32_WCE -# define LOADLIBARYEX L"LoadLibraryExW" -# else -# define LOADLIBARYEX "LoadLibraryExW" -# endif -#else -# define LOADLIBARYEX "LoadLibraryExA" -#endif - - -/* - * _Expat_LoadLibrary() - * - * This is used to dynamically load DLLs using the most secure method available - * for the version of Windows that we are running on. - * - * Parameters: - * - * filename [in] - The filename or full path of the DLL to load. If only the - * filename is passed then the DLL will be loaded from the - * Windows system directory. - * - * Returns the handle of the module on success; otherwise NULL. - */ -HMODULE _Expat_LoadLibrary(LPCTSTR filename) -{ - HMODULE hModule = NULL; - LOADLIBRARYEX_FN pLoadLibraryEx = NULL; - - /* Get a handle to kernel32 so we can access it's functions at runtime */ - HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32")); - if(!hKernel32) - return NULL; /* LCOV_EXCL_LINE */ - - /* Attempt to find LoadLibraryEx() which is only available on Windows 2000 - and above */ - pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX); - - /* Detect if there's already a path in the filename and load the library if - there is. Note: Both back slashes and forward slashes have been supported - since the earlier days of DOS at an API level although they are not - supported by command prompt */ - if(_tcspbrk(filename, TEXT("\\/"))) { - /** !checksrc! disable BANNEDFUNC 1 **/ - hModule = pLoadLibraryEx ? - pLoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : - LoadLibrary(filename); - } - /* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only - supported on Windows Vista, Windows Server 2008, Windows 7 and Windows - Server 2008 R2 with this patch or natively on Windows 8 and above */ - else if(pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) { - /* Load the DLL from the Windows system directory */ - hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); - } - else { - /* Attempt to get the Windows system path */ - UINT systemdirlen = GetSystemDirectory(NULL, 0); - if(systemdirlen) { - /* Allocate space for the full DLL path (Room for the null terminator - is included in systemdirlen) */ - size_t filenamelen = _tcslen(filename); - TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen)); - if(path && GetSystemDirectory(path, systemdirlen)) { - /* Calculate the full DLL path */ - _tcscpy(path + _tcslen(path), TEXT("\\")); - _tcscpy(path + _tcslen(path), filename); - - /* Load the DLL from the Windows system directory */ - /** !checksrc! disable BANNEDFUNC 1 **/ - hModule = pLoadLibraryEx ? - pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : - LoadLibrary(path); - - } - free(path); - } - } - - return hModule; -} - -#else /* defined(_WIN32) */ - -/* ISO C requires a translation unit to contain at least one declaration - [-Wempty-translation-unit] */ -typedef int _TRANSLATION_UNIT_LOAD_LIBRARY_C_NOT_EMTPY; - -#endif /* defined(_WIN32) */ diff --git a/Modules/expat/nametab.h b/Modules/expat/nametab.h index bfa2bd38cd95cd..3681df348eebd6 100644 --- a/Modules/expat/nametab.h +++ b/Modules/expat/nametab.h @@ -31,152 +31,106 @@ */ static const unsigned namingBitmap[] = { -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE, -0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF, -0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF, -0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, -0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, -0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, -0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, -0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, -0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, -0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000, -0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060, -0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, -0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003, -0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000, -0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, -0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003, -0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000, -0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, -0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003, -0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000, -0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000, -0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, -0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB, -0x40000000, 0xF580C900, 0x00000007, 0x02010800, -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF, -0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF, -0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, -0x00000000, 0x00004C40, 0x00000000, 0x00000000, -0x00000007, 0x00000000, 0x00000000, 0x00000000, -0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, -0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF, -0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000, -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000, -0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE, -0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, -0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, -0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000, -0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, -0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, -0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, -0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, -0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, -0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF, -0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, -0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF, -0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF, -0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, -0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0, -0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1, -0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, -0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80, -0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3, -0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, -0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, -0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000, -0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF, -0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x1FFF0000, 0x00000002, -0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, -0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x04000000, + 0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF, + 0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFE00F, 0xFC31FFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, + 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF0003, 0xFFFFFFFF, + 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, + 0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, 0x00000000, 0x07FFFFFE, + 0x000007FE, 0xFFFE0000, 0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060, + 0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, 0xFFF99FE0, 0x03C5FDFF, + 0xB0000000, 0x00030003, 0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000, + 0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, 0xFFF99FE0, 0x23CDFDFF, + 0xB0000000, 0x00000003, 0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000, + 0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, 0xFFFDDFE0, 0x03EFFDFF, + 0x40000000, 0x00000003, 0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x000D7FFF, + 0x0000003F, 0x00000000, 0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, 0x0007DAED, 0x50000000, + 0x82315001, 0x002C62AB, 0x40000000, 0xF580C900, 0x00000007, 0x02010800, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0FFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0x03FFFFFF, 0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF, + 0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, 0x00000000, 0x00004C40, + 0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000000, + 0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, 0x001FFFFF, 0xFFFFFFFE, + 0xFFFFFFFF, 0x07FFFFFF, 0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F, + 0x00000000, 0x00000000, 0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE, + 0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, 0x00FFFFFF, 0x00000000, + 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, 0xFFFFD7C0, 0xFFFFFFFB, + 0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, + 0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, + 0x027FFFFF, 0xFFFFFFFE, 0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF, + 0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, 0xFFFFFFFF, 0x7CFFFFFF, + 0xFFEF7FFF, 0x03FF3DFF, 0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF, + 0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, 0xFFF987E4, 0xD36DFDFF, + 0x5E003987, 0x001FFFC0, 0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1, + 0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, 0xD63DC7EC, 0xC3BFC718, + 0x00803DC7, 0x0000FF80, 0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3, + 0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3FFFDFF, + 0x00803DCF, 0x0000FFC3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, 0xFEF02596, 0x3BFF6CAE, + 0x03FF3F5F, 0x00000000, 0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF, + 0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1FFF0000, 0x00000002, + 0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0x661FFFFF, 0xFFFFFFFE, + 0xFFFFFFFF, 0x77FFFFFF, }; static const unsigned char nmstrtPages[] = { -0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, -0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, -0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, -0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, }; static const unsigned char namePages[] = { -0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, -0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, -0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, -0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, 0x00, 0x1F, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x26, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, }; diff --git a/Modules/expat/siphash.h b/Modules/expat/siphash.h index 4d6786d7839a2c..bfee65a332f1bf 100644 --- a/Modules/expat/siphash.h +++ b/Modules/expat/siphash.h @@ -11,6 +11,10 @@ * -------------------------------------------------------------------------- * HISTORY: * + * 2019-08-03 (Sebastian Pipping) + * - Mark part of sip24_valid as to be excluded from clang-format + * - Re-format code using clang-format 9 + * * 2018-07-08 (Anton Maklakov) * - Add "fall through" markers for GCC's -Wimplicit-fallthrough * @@ -94,186 +98,186 @@ #include /* size_t */ #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1600) - /* For vs2003/7.1 up to vs2008/9.0; _MSC_VER 1600 is vs2010/10.0 */ - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; - typedef unsigned __int64 uint64_t; +/* For vs2003/7.1 up to vs2008/9.0; _MSC_VER 1600 is vs2010/10.0 */ +typedef unsigned __int8 uint8_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; #else - #include /* uint64_t uint32_t uint8_t */ +# include /* uint64_t uint32_t uint8_t */ #endif - /* * Workaround to not require a C++11 compiler for using ULL suffix * 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_ROTL(x, b) (uint64_t)(((x) << (b)) | ( (x) >> (64 - (b)))) +#define _SIP_ULL(high, low) (((uint64_t)high << 32) | low) -#define SIP_U32TO8_LE(p, v) \ - (p)[0] = (uint8_t)((v) >> 0); (p)[1] = (uint8_t)((v) >> 8); \ - (p)[2] = (uint8_t)((v) >> 16); (p)[3] = (uint8_t)((v) >> 24); +#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) -#define SIP_U64TO8_LE(p, v) \ - SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0)); \ - SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); +#define SIP_U32TO8_LE(p, v) \ + (p)[0] = (uint8_t)((v) >> 0); \ + (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); \ + (p)[3] = (uint8_t)((v) >> 24); -#define SIP_U8TO64_LE(p) \ - (((uint64_t)((p)[0]) << 0) | \ - ((uint64_t)((p)[1]) << 8) | \ - ((uint64_t)((p)[2]) << 16) | \ - ((uint64_t)((p)[3]) << 24) | \ - ((uint64_t)((p)[4]) << 32) | \ - ((uint64_t)((p)[5]) << 40) | \ - ((uint64_t)((p)[6]) << 48) | \ - ((uint64_t)((p)[7]) << 56)) +#define SIP_U64TO8_LE(p, v) \ + SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0)); \ + SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); +#define SIP_U8TO64_LE(p) \ + (((uint64_t)((p)[0]) << 0) | ((uint64_t)((p)[1]) << 8) \ + | ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) \ + | ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) \ + | ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) -#define SIPHASH_INITIALIZER { 0, 0, 0, 0, { 0 }, 0, 0 } +#define SIPHASH_INITIALIZER \ + { 0, 0, 0, 0, {0}, 0, 0 } struct siphash { - uint64_t v0, v1, v2, v3; + uint64_t v0, v1, v2, v3; - unsigned char buf[8], *p; - uint64_t c; + unsigned char buf[8], *p; + uint64_t c; }; /* struct siphash */ - #define SIP_KEYLEN 16 struct sipkey { - uint64_t k[2]; + uint64_t k[2]; }; /* struct sipkey */ -#define sip_keyof(k) sip_tokey(&(struct sipkey){ { 0 } }, (k)) +#define sip_keyof(k) sip_tokey(&(struct sipkey){{0}}, (k)) -static struct sipkey *sip_tokey(struct sipkey *key, const void *src) { - key->k[0] = SIP_U8TO64_LE((const unsigned char *)src); - key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8); - return key; +static struct sipkey * +sip_tokey(struct sipkey *key, const void *src) { + key->k[0] = SIP_U8TO64_LE((const unsigned char *)src); + key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8); + return key; } /* sip_tokey() */ - #ifdef SIPHASH_TOBIN -#define sip_binof(v) sip_tobin((unsigned char[8]){ 0 }, (v)) +# define sip_binof(v) sip_tobin((unsigned char[8]){0}, (v)) -static void *sip_tobin(void *dst, uint64_t u64) { - SIP_U64TO8_LE((unsigned char *)dst, u64); - return dst; +static void * +sip_tobin(void *dst, uint64_t u64) { + SIP_U64TO8_LE((unsigned char *)dst, u64); + return dst; } /* sip_tobin() */ -#endif /* SIPHASH_TOBIN */ - +#endif /* SIPHASH_TOBIN */ -static void sip_round(struct siphash *H, const int rounds) { - int i; +static void +sip_round(struct siphash *H, const int rounds) { + int i; - for (i = 0; i < rounds; i++) { - H->v0 += H->v1; - H->v1 = SIP_ROTL(H->v1, 13); - H->v1 ^= H->v0; - H->v0 = SIP_ROTL(H->v0, 32); + for (i = 0; i < rounds; i++) { + H->v0 += H->v1; + H->v1 = SIP_ROTL(H->v1, 13); + H->v1 ^= H->v0; + H->v0 = SIP_ROTL(H->v0, 32); - H->v2 += H->v3; - H->v3 = SIP_ROTL(H->v3, 16); - H->v3 ^= H->v2; + H->v2 += H->v3; + H->v3 = SIP_ROTL(H->v3, 16); + H->v3 ^= H->v2; - H->v0 += H->v3; - H->v3 = SIP_ROTL(H->v3, 21); - H->v3 ^= H->v0; + H->v0 += H->v3; + H->v3 = SIP_ROTL(H->v3, 21); + H->v3 ^= H->v0; - H->v2 += H->v1; - H->v1 = SIP_ROTL(H->v1, 17); - H->v1 ^= H->v2; - H->v2 = SIP_ROTL(H->v2, 32); - } + H->v2 += H->v1; + H->v1 = SIP_ROTL(H->v1, 17); + H->v1 ^= H->v2; + H->v2 = SIP_ROTL(H->v2, 32); + } } /* sip_round() */ +static struct siphash * +sip24_init(struct siphash *H, const struct sipkey *key) { + H->v0 = _SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0]; + H->v1 = _SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1]; + H->v2 = _SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0]; + H->v3 = _SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1]; -static struct siphash *sip24_init(struct siphash *H, - const struct sipkey *key) { - H->v0 = _SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0]; - H->v1 = _SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1]; - H->v2 = _SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0]; - H->v3 = _SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1]; + H->p = H->buf; + H->c = 0; - H->p = H->buf; - H->c = 0; - - return H; + return H; } /* sip24_init() */ +#define sip_endof(a) (&(a)[sizeof(a) / sizeof *(a)]) -#define sip_endof(a) (&(a)[sizeof (a) / sizeof *(a)]) - -static struct siphash *sip24_update(struct siphash *H, const void *src, - size_t len) { - const unsigned char *p = (const unsigned char *)src, *pe = p + len; - uint64_t m; +static struct siphash * +sip24_update(struct siphash *H, const void *src, size_t len) { + const unsigned char *p = (const unsigned char *)src, *pe = p + len; + uint64_t m; - do { - while (p < pe && H->p < sip_endof(H->buf)) - *H->p++ = *p++; + do { + while (p < pe && H->p < sip_endof(H->buf)) + *H->p++ = *p++; - if (H->p < sip_endof(H->buf)) - break; + if (H->p < sip_endof(H->buf)) + break; - m = SIP_U8TO64_LE(H->buf); - H->v3 ^= m; - sip_round(H, 2); - H->v0 ^= m; + m = SIP_U8TO64_LE(H->buf); + H->v3 ^= m; + sip_round(H, 2); + H->v0 ^= m; - H->p = H->buf; - H->c += 8; - } while (p < pe); + H->p = H->buf; + H->c += 8; + } while (p < pe); - return H; + return H; } /* sip24_update() */ - -static uint64_t sip24_final(struct siphash *H) { - const char left = (char)(H->p - H->buf); - uint64_t b = (H->c + left) << 56; - - switch (left) { - case 7: b |= (uint64_t)H->buf[6] << 48; - /* fall through */ - case 6: b |= (uint64_t)H->buf[5] << 40; - /* fall through */ - case 5: b |= (uint64_t)H->buf[4] << 32; - /* fall through */ - case 4: b |= (uint64_t)H->buf[3] << 24; - /* fall through */ - case 3: b |= (uint64_t)H->buf[2] << 16; - /* fall through */ - case 2: b |= (uint64_t)H->buf[1] << 8; - /* fall through */ - case 1: b |= (uint64_t)H->buf[0] << 0; - /* fall through */ - case 0: break; - } - - H->v3 ^= b; - sip_round(H, 2); - H->v0 ^= b; - H->v2 ^= 0xff; - sip_round(H, 4); - - return H->v0 ^ H->v1 ^ H->v2 ^ H->v3; +static uint64_t +sip24_final(struct siphash *H) { + const char left = (char)(H->p - H->buf); + uint64_t b = (H->c + left) << 56; + + switch (left) { + case 7: + b |= (uint64_t)H->buf[6] << 48; + /* fall through */ + case 6: + b |= (uint64_t)H->buf[5] << 40; + /* fall through */ + case 5: + b |= (uint64_t)H->buf[4] << 32; + /* fall through */ + case 4: + b |= (uint64_t)H->buf[3] << 24; + /* fall through */ + case 3: + b |= (uint64_t)H->buf[2] << 16; + /* fall through */ + case 2: + b |= (uint64_t)H->buf[1] << 8; + /* fall through */ + case 1: + b |= (uint64_t)H->buf[0] << 0; + /* fall through */ + case 0: + break; + } + + H->v3 ^= b; + sip_round(H, 2); + H->v0 ^= b; + H->v2 ^= 0xff; + sip_round(H, 4); + + return H->v0 ^ H->v1 ^ H->v2 ^ H->v3; } /* sip24_final() */ - -static uint64_t siphash24(const void *src, size_t len, - const struct sipkey *key) { - struct siphash state = SIPHASH_INITIALIZER; - return sip24_final(sip24_update(sip24_init(&state, key), src, len)); +static uint64_t +siphash24(const void *src, size_t len, const struct sipkey *key) { + struct siphash state = SIPHASH_INITIALIZER; + return sip24_final(sip24_update(sip24_init(&state, key), src, len)); } /* siphash24() */ - /* * SipHash-2-4 output with * k = 00 01 02 ... @@ -285,107 +289,110 @@ static uint64_t siphash24(const void *src, size_t len, * ... * in = 00 01 02 ... 3e (63 bytes) */ -static int sip24_valid(void) { - static const unsigned char vectors[64][8] = { - { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, }, - { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, }, - { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, }, - { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, }, - { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, }, - { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, }, - { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, }, - { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, }, - { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, }, - { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, }, - { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, }, - { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, }, - { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, }, - { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, }, - { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, }, - { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, }, - { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, }, - { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, }, - { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, }, - { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, }, - { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, }, - { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, }, - { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, }, - { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, }, - { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, }, - { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, }, - { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, }, - { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, }, - { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, }, - { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, }, - { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, }, - { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, }, - { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, }, - { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, }, - { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, }, - { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, }, - { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, }, - { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, }, - { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, }, - { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, }, - { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, }, - { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, }, - { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, }, - { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, }, - { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, }, - { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, }, - { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, }, - { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, }, - { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, }, - { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, }, - { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, }, - { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, }, - { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, }, - { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, }, - { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, }, - { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, }, - { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, }, - { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, }, - { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, }, - { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, }, - { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, }, - { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, }, - { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, }, - { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, } - }; - unsigned char in[64]; - struct sipkey k; - size_t i; - - sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011" - "\012\013\014\015\016\017"); - - for (i = 0; i < sizeof in; ++i) { - in[i] = (unsigned char)i; - - if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i])) - return 0; - } - - return 1; +static int +sip24_valid(void) { + /* clang-format off */ + static const unsigned char vectors[64][8] = { + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, }, + { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, }, + { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, }, + { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, }, + { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, }, + { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, }, + { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, }, + { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, }, + { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, }, + { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, }, + { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, }, + { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, }, + { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, }, + { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, }, + { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, }, + { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, }, + { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, }, + { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, }, + { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, }, + { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, }, + { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, }, + { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, }, + { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, }, + { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, }, + { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, }, + { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, }, + { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, }, + { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, }, + { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, }, + { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, }, + { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, }, + { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, }, + { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, }, + { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, }, + { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, }, + { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, }, + { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, }, + { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, }, + { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, }, + { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, }, + { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, }, + { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, }, + { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, }, + { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, }, + { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, }, + { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, }, + { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, }, + { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, }, + { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, }, + { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, }, + { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, }, + { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, }, + { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, }, + { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, }, + { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, }, + { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, }, + { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, }, + { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, }, + { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, }, + { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, }, + { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, }, + { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, }, + { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, }, + { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, } + }; + /* clang-format on */ + + unsigned char in[64]; + struct sipkey k; + size_t i; + + sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011" + "\012\013\014\015\016\017"); + + for (i = 0; i < sizeof in; ++i) { + in[i] = (unsigned char)i; + + if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i])) + return 0; + } + + return 1; } /* sip24_valid() */ - #ifdef SIPHASH_MAIN -#include +# include -int main(void) { - const int ok = sip24_valid(); +int +main(void) { + const int ok = sip24_valid(); - if (ok) - puts("OK"); - else - puts("FAIL"); + if (ok) + puts("OK"); + else + puts("FAIL"); - return !ok; + return ! ok; } /* main() */ #endif /* SIPHASH_MAIN */ - #endif /* SIPHASH_H */ diff --git a/Modules/expat/utf8tab.h b/Modules/expat/utf8tab.h index fa0bed6f5d751d..a22986acbb9526 100644 --- a/Modules/expat/utf8tab.h +++ b/Modules/expat/utf8tab.h @@ -31,34 +31,34 @@ */ /* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, -/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, -/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, -/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, -/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, -/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, + /* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, + /* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, + /* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, + /* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, + /* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, + /* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, diff --git a/Modules/expat/winconfig.h b/Modules/expat/winconfig.h index 17fea4689001f4..562a4a82dc1d63 100644 --- a/Modules/expat/winconfig.h +++ b/Modules/expat/winconfig.h @@ -40,24 +40,17 @@ #include #include +#if defined(HAVE_EXPAT_CONFIG_H) /* e.g. MinGW */ +# include +#else /* !defined(HAVE_EXPAT_CONFIG_H) */ -#if defined(HAVE_EXPAT_CONFIG_H) /* e.g. MinGW */ -# include -#else /* !defined(HAVE_EXPAT_CONFIG_H) */ - - -#define XML_NS 1 -#define XML_DTD 1 -#define XML_CONTEXT_BYTES 1024 +# define XML_NS 1 +# define XML_DTD 1 +# define XML_CONTEXT_BYTES 1024 /* we will assume all Windows platforms are little endian */ -#define BYTEORDER 1234 - -/* Windows has memmove() available. */ -#define HAVE_MEMMOVE - +# define BYTEORDER 1234 #endif /* !defined(HAVE_EXPAT_CONFIG_H) */ - #endif /* ndef WINCONFIG_H */ diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index c4f3ffc215c9ef..e740f0e19c7d4a 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,4 +1,4 @@ -/* 19ac4776051591216f1874e34ee99b6a43a3784c8bd7d70efeb9258dd22b906a (2.2.6+) +/* f2d0ab6d1d4422a08cf1cf3bbdfba96b49dea42fb5ff4615e03a2a25c306e769 (2.2.8+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -30,33 +30,38 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined(_GNU_SOURCE) -# define _GNU_SOURCE 1 /* syscall prototype */ +#if ! defined(_GNU_SOURCE) +# define _GNU_SOURCE 1 /* syscall prototype */ +#endif + +#ifdef _WIN32 +/* force stdlib to define rand_s() */ +# define _CRT_RAND_S #endif #include -#include /* memset(), memcpy() */ +#include /* memset(), memcpy() */ #include -#include /* UINT_MAX */ -#include /* fprintf */ -#include /* getenv */ +#include /* UINT_MAX */ +#include /* fprintf */ +#include /* getenv, rand_s */ #ifdef _WIN32 -#define getpid GetCurrentProcessId +# define getpid GetCurrentProcessId #else -#include /* gettimeofday() */ -#include /* getpid() */ -#include /* getpid() */ -#include /* O_RDONLY */ -#include +# include /* gettimeofday() */ +# include /* getpid() */ +# include /* getpid() */ +# include /* O_RDONLY */ +# include #endif #define XML_BUILDING_EXPAT 1 #ifdef _WIN32 -#include "winconfig.h" +# include "winconfig.h" #elif defined(HAVE_EXPAT_CONFIG_H) -#include +# include #endif /* ndef _WIN32 */ #include "ascii.h" @@ -64,33 +69,31 @@ #include "siphash.h" #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) -# if defined(HAVE_GETRANDOM) -# include /* getrandom */ -# else -# include /* syscall */ -# include /* SYS_getrandom */ -# endif -# if ! defined(GRND_NONBLOCK) -# define GRND_NONBLOCK 0x0001 -# endif /* defined(GRND_NONBLOCK) */ -#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ - -#if defined(HAVE_LIBBSD) \ +# if defined(HAVE_GETRANDOM) +# include /* getrandom */ +# else +# include /* syscall */ +# include /* SYS_getrandom */ +# endif +# if ! defined(GRND_NONBLOCK) +# define GRND_NONBLOCK 0x0001 +# endif /* defined(GRND_NONBLOCK) */ +#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ + +#if defined(HAVE_LIBBSD) \ && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM)) -# include +# include #endif -#if defined(_WIN32) && !defined(LOAD_LIBRARY_SEARCH_SYSTEM32) -# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 +#if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32) +# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 #endif -#if !defined(HAVE_GETRANDOM) && !defined(HAVE_SYSCALL_GETRANDOM) \ - && !defined(HAVE_ARC4RANDOM_BUF) && !defined(HAVE_ARC4RANDOM) \ - && !defined(XML_DEV_URANDOM) \ - && !defined(_WIN32) \ - && !defined(XML_POOR_ENTROPY) -# error \ - You do not have support for any sources of high quality entropy \ +#if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \ + && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) \ + && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32) \ + && ! defined(XML_POOR_ENTROPY) +# error You do not have support for any sources of high quality entropy \ enabled. For end user security, that is probably not what you want. \ \ Your options include: \ @@ -101,7 +104,7 @@ * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \ - * Windows (RtlGenRandom): _WIN32. \ + * Windows (rand_s): _WIN32. \ \ If insist on not using any of these, bypass this error by defining \ XML_POOR_ENTROPY; you have been warned. \ @@ -110,69 +113,59 @@ to the build system, please open a bug. Thank you! #endif - #ifdef XML_UNICODE -#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX -#define XmlConvert XmlUtf16Convert -#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding -#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS -#define XmlEncode XmlUtf16Encode +# define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX +# define XmlConvert XmlUtf16Convert +# define XmlGetInternalEncoding XmlGetUtf16InternalEncoding +# define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS +# define XmlEncode XmlUtf16Encode /* Using pointer subtraction to convert to integer type. */ -#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1)) +# define MUST_CONVERT(enc, s) \ + (! (enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1)) typedef unsigned short ICHAR; #else -#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX -#define XmlConvert XmlUtf8Convert -#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding -#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS -#define XmlEncode XmlUtf8Encode -#define MUST_CONVERT(enc, s) (!(enc)->isUtf8) +# define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX +# define XmlConvert XmlUtf8Convert +# define XmlGetInternalEncoding XmlGetUtf8InternalEncoding +# define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS +# define XmlEncode XmlUtf8Encode +# define MUST_CONVERT(enc, s) (! (enc)->isUtf8) typedef char ICHAR; #endif - #ifndef XML_NS -#define XmlInitEncodingNS XmlInitEncoding -#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding -#undef XmlGetInternalEncodingNS -#define XmlGetInternalEncodingNS XmlGetInternalEncoding -#define XmlParseXmlDeclNS XmlParseXmlDecl +# define XmlInitEncodingNS XmlInitEncoding +# define XmlInitUnknownEncodingNS XmlInitUnknownEncoding +# undef XmlGetInternalEncodingNS +# define XmlGetInternalEncodingNS XmlGetInternalEncoding +# define XmlParseXmlDeclNS XmlParseXmlDecl #endif #ifdef XML_UNICODE -#ifdef XML_UNICODE_WCHAR_T -#define XML_T(x) (const wchar_t)x -#define XML_L(x) L ## x -#else -#define XML_T(x) (const unsigned short)x -#define XML_L(x) x -#endif +# ifdef XML_UNICODE_WCHAR_T +# define XML_T(x) (const wchar_t) x +# define XML_L(x) L##x +# else +# define XML_T(x) (const unsigned short)x +# define XML_L(x) x +# endif #else -#define XML_T(x) x -#define XML_L(x) x +# define XML_T(x) x +# define XML_L(x) x #endif /* Round up n to be a multiple of sz, where sz is a power of 2. */ -#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) +#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1)) /* Do safe (NULL-aware) pointer arithmetic */ #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0) -/* Handle the case where memmove() doesn't exist. */ -#ifndef HAVE_MEMMOVE -#ifdef HAVE_BCOPY -#define memmove(d,s,l) bcopy((s),(d),(l)) -#else -#error memmove does not exist on this platform, nor is a substitute available -#endif /* HAVE_BCOPY */ -#endif /* HAVE_MEMMOVE */ - #include "internal.h" #include "xmltok.h" #include "xmlrole.h" @@ -191,11 +184,9 @@ typedef struct { const XML_Memory_Handling_Suite *mem; } HASH_TABLE; -static size_t -keylen(KEY s); +static size_t keylen(KEY s); -static void -copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key); +static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key); /* For probing (after a collision) we need a step size relative prime to the hash table size, which is a power of 2. We use double-hashing, @@ -205,9 +196,9 @@ copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key); We limit the maximum step size to table->size / 4 (mask >> 2) and make it odd, since odd numbers are always relative prime to a power of 2. */ -#define SECOND_HASH(hash, mask, power) \ - ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2)) -#define PROBE_STEP(hash, mask, power) \ +#define SECOND_HASH(hash, mask, power) \ + ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2)) +#define PROBE_STEP(hash, mask, power) \ ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) typedef struct { @@ -215,7 +206,7 @@ typedef struct { NAMED **end; } HASH_TABLE_ITER; -#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ +#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ #define INIT_DATA_BUF_SIZE 1024 #define INIT_ATTS_SIZE 16 #define INIT_ATTS_VERSION 0xFFFFFFFF @@ -262,20 +253,20 @@ typedef struct { TAG objects in a free list. */ typedef struct tag { - struct tag *parent; /* parent of this element */ - const char *rawName; /* tagName in the original encoding */ + struct tag *parent; /* parent of this element */ + const char *rawName; /* tagName in the original encoding */ int rawNameLength; - TAG_NAME name; /* tagName in the API encoding */ - char *buf; /* buffer for name components */ - char *bufEnd; /* end of the buffer */ + TAG_NAME name; /* tagName in the API encoding */ + char *buf; /* buffer for name components */ + char *bufEnd; /* end of the buffer */ BINDING *bindings; } TAG; typedef struct { const XML_Char *name; const XML_Char *textPtr; - int textLen; /* length in XML_Chars */ - int processed; /* # of processed bytes - when suspended */ + int textLen; /* length in XML_Chars */ + int processed; /* # of processed bytes - when suspended */ const XML_Char *systemId; const XML_Char *base; const XML_Char *publicId; @@ -286,13 +277,13 @@ typedef struct { } ENTITY; typedef struct { - enum XML_Content_Type type; - enum XML_Content_Quant quant; - const XML_Char * name; - int firstchild; - int lastchild; - int childcnt; - int nextsib; + enum XML_Content_Type type; + enum XML_Content_Quant quant; + const XML_Char *name; + int firstchild; + int lastchild; + int childcnt; + int nextsib; } CONTENT_SCAFFOLD; #define INIT_SCAFFOLD_ELEMENTS 32 @@ -380,10 +371,8 @@ typedef struct open_internal_entity { XML_Bool betweenDecl; /* WFC: PE Between Declarations */ } OPEN_INTERNAL_ENTITY; -typedef enum XML_Error PTRCALL Processor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr); +typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start, + const char *end, const char **endPtr); static Processor prologProcessor; static Processor prologInitProcessor; @@ -404,118 +393,101 @@ static Processor externalEntityInitProcessor3; static Processor externalEntityContentProcessor; static Processor internalEntityProcessor; -static enum XML_Error -handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); -static enum XML_Error -processXmlDecl(XML_Parser parser, int isGeneralTextEntity, - const char *s, const char *next); -static enum XML_Error -initializeEncoding(XML_Parser parser); -static enum XML_Error -doProlog(XML_Parser parser, const ENCODING *enc, const char *s, - const char *end, int tok, const char *next, const char **nextPtr, - XML_Bool haveMore); -static enum XML_Error -processInternalEntity(XML_Parser parser, ENTITY *entity, - XML_Bool betweenDecl); -static enum XML_Error -doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, - const char *start, const char *end, const char **endPtr, - XML_Bool haveMore); -static enum XML_Error -doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, - const char *end, const char **nextPtr, XML_Bool haveMore); +static enum XML_Error handleUnknownEncoding(XML_Parser parser, + const XML_Char *encodingName); +static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, + const char *s, const char *next); +static enum XML_Error initializeEncoding(XML_Parser parser); +static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc, + const char *s, const char *end, int tok, + const char *next, const char **nextPtr, + XML_Bool haveMore, XML_Bool allowClosingDoctype); +static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity, + XML_Bool betweenDecl); +static enum XML_Error doContent(XML_Parser parser, int startTagLevel, + const ENCODING *enc, const char *start, + const char *end, const char **endPtr, + XML_Bool haveMore); +static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *, + const char **startPtr, const char *end, + const char **nextPtr, XML_Bool haveMore); #ifdef XML_DTD -static enum XML_Error -doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, - const char *end, const char **nextPtr, XML_Bool haveMore); +static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *, + const char **startPtr, const char *end, + const char **nextPtr, XML_Bool haveMore); #endif /* XML_DTD */ -static void -freeBindings(XML_Parser parser, BINDING *bindings); -static enum XML_Error -storeAtts(XML_Parser parser, const ENCODING *, const char *s, - TAG_NAME *tagNamePtr, BINDING **bindingsPtr); -static enum XML_Error -addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, - const XML_Char *uri, BINDING **bindingsPtr); -static int -defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, - XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser); -static enum XML_Error -storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, - const char *, const char *, STRING_POOL *); -static enum XML_Error -appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, - const char *, const char *, STRING_POOL *); -static ATTRIBUTE_ID * -getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, - const char *end); -static int -setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); -static enum XML_Error -storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, - const char *end); -static int -reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, - const char *start, const char *end); -static int -reportComment(XML_Parser parser, const ENCODING *enc, const char *start, - const char *end); -static void -reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, - const char *end); - -static const XML_Char * getContext(XML_Parser parser); -static XML_Bool -setContext(XML_Parser parser, const XML_Char *context); +static void freeBindings(XML_Parser parser, BINDING *bindings); +static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, + const char *s, TAG_NAME *tagNamePtr, + BINDING **bindingsPtr); +static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, + const ATTRIBUTE_ID *attId, const XML_Char *uri, + BINDING **bindingsPtr); +static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, + XML_Bool isId, const XML_Char *dfltValue, + XML_Parser parser); +static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *, + XML_Bool isCdata, const char *, + const char *, STRING_POOL *); +static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *, + XML_Bool isCdata, const char *, + const char *, STRING_POOL *); +static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end); +static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); +static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end); +static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end); +static int reportComment(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end); +static void reportDefault(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end); + +static const XML_Char *getContext(XML_Parser parser); +static XML_Bool setContext(XML_Parser parser, const XML_Char *context); static void FASTCALL normalizePublicId(XML_Char *s); -static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms); +static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms); /* do not call if m_parentParser != NULL */ static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms); -static void -dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms); -static int -dtdCopy(XML_Parser oldParser, - DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms); -static int -copyEntityTable(XML_Parser oldParser, - HASH_TABLE *, STRING_POOL *, const HASH_TABLE *); -static NAMED * -lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize); -static void FASTCALL -hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms); +static void dtdDestroy(DTD *p, XML_Bool isDocEntity, + const XML_Memory_Handling_Suite *ms); +static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, + const XML_Memory_Handling_Suite *ms); +static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *, + const HASH_TABLE *); +static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name, + size_t createSize); +static void FASTCALL hashTableInit(HASH_TABLE *, + const XML_Memory_Handling_Suite *ms); static void FASTCALL hashTableClear(HASH_TABLE *); static void FASTCALL hashTableDestroy(HASH_TABLE *); -static void FASTCALL -hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); -static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *); +static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); +static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *); -static void FASTCALL -poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms); +static void FASTCALL poolInit(STRING_POOL *, + const XML_Memory_Handling_Suite *ms); static void FASTCALL poolClear(STRING_POOL *); static void FASTCALL poolDestroy(STRING_POOL *); -static XML_Char * -poolAppend(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end); -static XML_Char * -poolStoreString(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end); +static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, + const char *ptr, const char *end); +static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, + const char *ptr, const char *end); static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); -static const XML_Char * FASTCALL -poolCopyString(STRING_POOL *pool, const XML_Char *s); -static const XML_Char * -poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n); -static const XML_Char * FASTCALL -poolAppendString(STRING_POOL *pool, const XML_Char *s); +static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool, + const XML_Char *s); +static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, + int n); +static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool, + const XML_Char *s); static int FASTCALL nextScaffoldPart(XML_Parser parser); -static XML_Content * build_model(XML_Parser parser); -static ELEMENT_TYPE * -getElementType(XML_Parser parser, const ENCODING *enc, - const char *ptr, const char *end); +static XML_Content *build_model(XML_Parser parser); +static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc, + const char *ptr, const char *end); static XML_Char *copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite); @@ -523,14 +495,11 @@ static XML_Char *copyString(const XML_Char *s, static unsigned long generate_hash_secret_salt(XML_Parser parser); static XML_Bool startParsing(XML_Parser parser); -static XML_Parser -parserCreate(const XML_Char *encodingName, - const XML_Memory_Handling_Suite *memsuite, - const XML_Char *nameSep, - DTD *dtd); +static XML_Parser parserCreate(const XML_Char *encodingName, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *nameSep, DTD *dtd); -static void -parserInit(XML_Parser parser, const XML_Char *encodingName); +static void parserInit(XML_Parser parser, const XML_Char *encodingName); #define poolStart(pool) ((pool)->start) #define poolEnd(pool) ((pool)->ptr) @@ -539,10 +508,10 @@ parserInit(XML_Parser parser, const XML_Char *encodingName); #define poolLastChar(pool) (((pool)->ptr)[-1]) #define poolDiscard(pool) ((pool)->ptr = (pool)->start) #define poolFinish(pool) ((pool)->start = (pool)->ptr) -#define poolAppendChar(pool, c) \ - (((pool)->ptr == (pool)->end && !poolGrow(pool)) \ - ? 0 \ - : ((*((pool)->ptr)++ = c), 1)) +#define poolAppendChar(pool, c) \ + (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \ + ? 0 \ + : ((*((pool)->ptr)++ = c), 1)) struct XML_ParserStruct { /* The first member must be m_userData so that the XML_GetUserData @@ -593,7 +562,7 @@ struct XML_ParserStruct { void *m_unknownEncodingMem; void *m_unknownEncodingData; void *m_unknownEncodingHandlerData; - void (XMLCALL *m_unknownEncodingRelease)(void *); + void(XMLCALL *m_unknownEncodingRelease)(void *); PROLOG_STATE m_prologState; Processor *m_processor; enum XML_Error m_errorCode; @@ -647,57 +616,55 @@ struct XML_ParserStruct { unsigned long m_hash_secret_salt; }; -#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s))) -#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p),(s))) -#define FREE(parser, p) (parser->m_mem.free_fcn((p))) - +#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s))) +#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s))) +#define FREE(parser, p) (parser->m_mem.free_fcn((p))) XML_Parser XMLCALL -XML_ParserCreate(const XML_Char *encodingName) -{ +XML_ParserCreate(const XML_Char *encodingName) { return XML_ParserCreate_MM(encodingName, NULL, NULL); } XML_Parser XMLCALL -XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) -{ +XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { XML_Char tmp[2]; *tmp = nsSep; return XML_ParserCreate_MM(encodingName, NULL, tmp); } -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, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, - ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, - ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, - ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, - ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0' -}; - +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, + ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, + ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, + ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, + ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, + ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, + ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, + '\0'}; /* To avoid warnings about unused functions: */ #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) -#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) +# if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) /* Obtain entropy on Linux 3.17+ */ static int -writeRandomBytes_getrandom_nonblock(void * target, size_t count) { - int success = 0; /* full count bytes written? */ +writeRandomBytes_getrandom_nonblock(void *target, size_t count) { + int success = 0; /* full count bytes written? */ size_t bytesWrittenTotal = 0; const unsigned int getrandomFlags = GRND_NONBLOCK; do { - void * const currentTarget = (void*)((char*)target + bytesWrittenTotal); + void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); const size_t bytesToWrite = count - bytesWrittenTotal; const int bytesWrittenMore = -#if defined(HAVE_GETRANDOM) +# if defined(HAVE_GETRANDOM) getrandom(currentTarget, bytesToWrite, getrandomFlags); -#else +# else syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags); -#endif +# endif if (bytesWrittenMore > 0) { bytesWrittenTotal += bytesWrittenMore; @@ -709,15 +676,14 @@ writeRandomBytes_getrandom_nonblock(void * target, size_t count) { return success; } -#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ +# endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ - -#if ! defined(_WIN32) && defined(XML_DEV_URANDOM) +# if ! defined(_WIN32) && defined(XML_DEV_URANDOM) /* Extract entropy from /dev/urandom */ static int -writeRandomBytes_dev_urandom(void * target, size_t count) { - int success = 0; /* full count bytes written? */ +writeRandomBytes_dev_urandom(void *target, size_t count) { + int success = 0; /* full count bytes written? */ size_t bytesWrittenTotal = 0; const int fd = open("/dev/urandom", O_RDONLY); @@ -726,7 +692,7 @@ writeRandomBytes_dev_urandom(void * target, size_t count) { } do { - void * const currentTarget = (void*)((char*)target + bytesWrittenTotal); + void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); const size_t bytesToWrite = count - bytesWrittenTotal; const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite); @@ -742,15 +708,14 @@ writeRandomBytes_dev_urandom(void * target, size_t count) { return success; } -#endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ - -#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ +# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ +#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ -#if defined(HAVE_ARC4RANDOM) +#if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) static void -writeRandomBytes_arc4random(void * target, size_t count) { +writeRandomBytes_arc4random(void *target, size_t count) { size_t bytesWrittenTotal = 0; while (bytesWrittenTotal < count) { @@ -758,93 +723,82 @@ writeRandomBytes_arc4random(void * target, size_t count) { size_t i = 0; for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); - i++, bytesWrittenTotal++) { + i++, bytesWrittenTotal++) { const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); ((uint8_t *)target)[bytesWrittenTotal] = random8; } } } -#endif /* defined(HAVE_ARC4RANDOM) */ - +#endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */ #ifdef _WIN32 -typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG); -HMODULE _Expat_LoadLibrary(LPCTSTR filename); /* see loadlibrary.c */ - -/* Obtain entropy on Windows XP / Windows Server 2003 and later. - * Hint on RtlGenRandom and the following article from libsodium. - * - * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI - * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/ +/* Obtain entropy on Windows using the rand_s() function which + * generates cryptographically secure random numbers. Internally it + * uses RtlGenRandom API which is present in Windows XP and later. */ static int -writeRandomBytes_RtlGenRandom(void * target, size_t count) { - int success = 0; /* full count bytes written? */ - const HMODULE advapi32 = _Expat_LoadLibrary(TEXT("ADVAPI32.DLL")); - - if (advapi32) { - const RTLGENRANDOM_FUNC RtlGenRandom - = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036"); - if (RtlGenRandom) { - if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) { - success = 1; - } +writeRandomBytes_rand_s(void *target, size_t count) { + size_t bytesWrittenTotal = 0; + + while (bytesWrittenTotal < count) { + unsigned int random32 = 0; + size_t i = 0; + + if (rand_s(&random32)) + return 0; /* failure */ + + for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); + i++, bytesWrittenTotal++) { + const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); + ((uint8_t *)target)[bytesWrittenTotal] = random8; } - FreeLibrary(advapi32); } - - return success; + return 1; /* success */ } #endif /* _WIN32 */ - #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) static unsigned long -gather_time_entropy(void) -{ -#ifdef _WIN32 +gather_time_entropy(void) { +# ifdef _WIN32 FILETIME ft; GetSystemTimeAsFileTime(&ft); /* never fails */ return ft.dwHighDateTime ^ ft.dwLowDateTime; -#else +# else struct timeval tv; int gettimeofday_res; gettimeofday_res = gettimeofday(&tv, NULL); -#if defined(NDEBUG) +# if defined(NDEBUG) (void)gettimeofday_res; -#else - assert (gettimeofday_res == 0); -#endif /* defined(NDEBUG) */ +# else + assert(gettimeofday_res == 0); +# endif /* defined(NDEBUG) */ /* Microseconds time is <20 bits entropy */ return tv.tv_usec; -#endif +# endif } -#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ - +#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ static unsigned long -ENTROPY_DEBUG(const char * label, unsigned long entropy) { - const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG"); +ENTROPY_DEBUG(const char *label, unsigned long entropy) { + const char *const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG"); if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) { - fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", - label, - (int)sizeof(entropy) * 2, entropy, - (unsigned long)sizeof(entropy)); + fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", label, + (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy)); } return entropy; } static unsigned long -generate_hash_secret_salt(XML_Parser parser) -{ +generate_hash_secret_salt(XML_Parser parser) { unsigned long entropy; (void)parser; @@ -857,20 +811,20 @@ generate_hash_secret_salt(XML_Parser parser) return ENTROPY_DEBUG("arc4random", entropy); #else /* Try high quality providers first .. */ -#ifdef _WIN32 - if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) { - return ENTROPY_DEBUG("RtlGenRandom", entropy); +# ifdef _WIN32 + if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) { + return ENTROPY_DEBUG("rand_s", entropy); } -#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) +# elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) { return ENTROPY_DEBUG("getrandom", entropy); } -#endif -#if ! defined(_WIN32) && defined(XML_DEV_URANDOM) +# endif +# if ! defined(_WIN32) && defined(XML_DEV_URANDOM) if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) { return ENTROPY_DEBUG("/dev/urandom", entropy); } -#endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ +# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ /* .. and self-made low quality for backup: */ /* Process ID is 0 bits entropy if attacker has local access */ @@ -881,7 +835,7 @@ generate_hash_secret_salt(XML_Parser parser) return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647); } else { return ENTROPY_DEBUG("fallback(8)", - entropy * (unsigned long)2305843009213693951ULL); + entropy * (unsigned long)2305843009213693951ULL); } #endif } @@ -893,49 +847,43 @@ get_hash_secret_salt(XML_Parser parser) { return parser->m_hash_secret_salt; } -static XML_Bool /* only valid for root parser */ -startParsing(XML_Parser parser) -{ - /* hash functions must be initialized before setContext() is called */ - if (parser->m_hash_secret_salt == 0) - parser->m_hash_secret_salt = generate_hash_secret_salt(parser); - if (parser->m_ns) { - /* implicit context only set for root parser, since child - parsers (i.e. external entity parsers) will inherit it - */ - return setContext(parser, implicitContext); - } - return XML_TRUE; +static XML_Bool /* only valid for root parser */ +startParsing(XML_Parser parser) { + /* hash functions must be initialized before setContext() is called */ + if (parser->m_hash_secret_salt == 0) + parser->m_hash_secret_salt = generate_hash_secret_salt(parser); + if (parser->m_ns) { + /* implicit context only set for root parser, since child + parsers (i.e. external entity parsers) will inherit it + */ + return setContext(parser, implicitContext); + } + return XML_TRUE; } XML_Parser XMLCALL XML_ParserCreate_MM(const XML_Char *encodingName, const XML_Memory_Handling_Suite *memsuite, - const XML_Char *nameSep) -{ + const XML_Char *nameSep) { return parserCreate(encodingName, memsuite, nameSep, NULL); } static XML_Parser parserCreate(const XML_Char *encodingName, - const XML_Memory_Handling_Suite *memsuite, - const XML_Char *nameSep, - DTD *dtd) -{ + const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep, + DTD *dtd) { XML_Parser parser; if (memsuite) { XML_Memory_Handling_Suite *mtemp; - parser = (XML_Parser) - memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); + parser = (XML_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; mtemp->realloc_fcn = memsuite->realloc_fcn; mtemp->free_fcn = memsuite->free_fcn; } - } - else { + } else { XML_Memory_Handling_Suite *mtemp; parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct)); if (parser != NULL) { @@ -946,27 +894,30 @@ parserCreate(const XML_Char *encodingName, } } - if (!parser) + if (! parser) return parser; parser->m_buffer = NULL; parser->m_bufferLim = NULL; parser->m_attsSize = INIT_ATTS_SIZE; - parser->m_atts = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE)); + parser->m_atts + = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE)); if (parser->m_atts == NULL) { FREE(parser, parser); return NULL; } #ifdef XML_ATTR_INFO - parser->m_attInfo = (XML_AttrInfo*)MALLOC(parser, parser->m_attsSize * sizeof(XML_AttrInfo)); + parser->m_attInfo = (XML_AttrInfo *)MALLOC( + parser, parser->m_attsSize * sizeof(XML_AttrInfo)); if (parser->m_attInfo == NULL) { FREE(parser, parser->m_atts); FREE(parser, parser); return NULL; } #endif - parser->m_dataBuf = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char)); + parser->m_dataBuf + = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char)); if (parser->m_dataBuf == NULL) { FREE(parser, parser->m_atts); #ifdef XML_ATTR_INFO @@ -1016,7 +967,7 @@ parserCreate(const XML_Char *encodingName, poolInit(&parser->m_temp2Pool, &(parser->m_mem)); parserInit(parser, encodingName); - if (encodingName && !parser->m_protocolEncodingName) { + if (encodingName && ! parser->m_protocolEncodingName) { XML_ParserFree(parser); return NULL; } @@ -1025,8 +976,7 @@ parserCreate(const XML_Char *encodingName, parser->m_ns = XML_TRUE; parser->m_internalEncoding = XmlGetInternalEncodingNS(); parser->m_namespaceSeparator = *nameSep; - } - else { + } else { parser->m_internalEncoding = XmlGetInternalEncoding(); } @@ -1034,8 +984,7 @@ parserCreate(const XML_Char *encodingName, } static void -parserInit(XML_Parser parser, const XML_Char *encodingName) -{ +parserInit(XML_Parser parser, const XML_Char *encodingName) { parser->m_processor = prologInitProcessor; XmlPrologStateInit(&parser->m_prologState); if (encodingName != NULL) { @@ -1108,8 +1057,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) /* moves list of bindings to m_freeBindingList */ static void FASTCALL -moveToFreeBindingList(XML_Parser parser, BINDING *bindings) -{ +moveToFreeBindingList(XML_Parser parser, BINDING *bindings) { while (bindings) { BINDING *b = bindings; bindings = bindings->nextTagBinding; @@ -1119,13 +1067,12 @@ moveToFreeBindingList(XML_Parser parser, BINDING *bindings) } XML_Bool XMLCALL -XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) -{ +XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { TAG *tStk; OPEN_INTERNAL_ENTITY *openEntityList; if (parser == NULL) - return XML_FALSE; + return XML_FALSE; if (parser->m_parentParser) return XML_FALSE; @@ -1161,15 +1108,15 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) } enum XML_Status XMLCALL -XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) -{ +XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) { if (parser == NULL) - return XML_STATUS_ERROR; + return XML_STATUS_ERROR; /* Block after XML_Parse()/XML_ParseBuffer() has been called. XXX There's no way for the caller to determine which of the XXX possible error cases caused the XML_STATUS_ERROR return. */ - if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) + if (parser->m_parsingStatus.parsing == XML_PARSING + || parser->m_parsingStatus.parsing == XML_SUSPENDED) return XML_STATUS_ERROR; /* Get rid of any previous encoding name */ @@ -1181,17 +1128,15 @@ XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) else { /* Copy the new encoding name into allocated memory */ parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); - if (!parser->m_protocolEncodingName) + if (! parser->m_protocolEncodingName) return XML_STATUS_ERROR; } return XML_STATUS_OK; } XML_Parser XMLCALL -XML_ExternalEntityParserCreate(XML_Parser oldParser, - const XML_Char *context, - const XML_Char *encodingName) -{ +XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, + const XML_Char *encodingName) { XML_Parser parser = oldParser; DTD *newDtd = NULL; DTD *oldDtd; @@ -1215,7 +1160,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, XML_AttlistDeclHandler oldAttlistDeclHandler; XML_EntityDeclHandler oldEntityDeclHandler; XML_XmlDeclHandler oldXmlDeclHandler; - ELEMENT_TYPE * oldDeclElementType; + ELEMENT_TYPE *oldDeclElementType; void *oldUserData; void *oldHandlerArg; @@ -1278,7 +1223,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, oldhash_secret_salt = parser->m_hash_secret_salt; #ifdef XML_DTD - if (!context) + if (! context) newDtd = oldDtd; #endif /* XML_DTD */ @@ -1291,12 +1236,11 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, XML_Char tmp[2]; *tmp = parser->m_namespaceSeparator; parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); - } - else { + } else { parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); } - if (!parser) + if (! parser) return NULL; parser->m_startElementHandler = oldStartElementHandler; @@ -1336,21 +1280,20 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, parser->m_prologState.inEntityValue = oldInEntityValue; if (context) { #endif /* XML_DTD */ - if (!dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem) - || !setContext(parser, context)) { + if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem) + || ! setContext(parser, context)) { XML_ParserFree(parser); return NULL; } parser->m_processor = externalEntityInitProcessor; #ifdef XML_DTD - } - else { - /* The DTD instance referenced by parser->m_dtd is shared between the document's - root parser and external PE parsers, therefore one does not need to - call setContext. In addition, one also *must* not call setContext, - because this would overwrite existing prefix->binding pointers in - parser->m_dtd with ones that get destroyed with the external PE parser. - This would leave those prefixes with dangling pointers. + } else { + /* The DTD instance referenced by parser->m_dtd is shared between the + document's root parser and external PE parsers, therefore one does not + need to call setContext. In addition, one also *must* not call + setContext, because this would overwrite existing prefix->binding + pointers in parser->m_dtd with ones that get destroyed with the external + PE parser. This would leave those prefixes with dangling pointers. */ parser->m_isParamEntity = XML_TRUE; XmlPrologStateInitExternalEntity(&parser->m_prologState); @@ -1361,11 +1304,10 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, } static void FASTCALL -destroyBindings(BINDING *bindings, XML_Parser parser) -{ +destroyBindings(BINDING *bindings, XML_Parser parser) { for (;;) { BINDING *b = bindings; - if (!b) + if (! b) break; bindings = b->nextTagBinding; FREE(parser, b->uri); @@ -1374,8 +1316,7 @@ destroyBindings(BINDING *bindings, XML_Parser parser) } void XMLCALL -XML_ParserFree(XML_Parser parser) -{ +XML_ParserFree(XML_Parser parser) { TAG *tagList; OPEN_INTERNAL_ENTITY *entityList; if (parser == NULL) @@ -1420,11 +1361,12 @@ XML_ParserFree(XML_Parser parser) /* external parameter entity parsers share the DTD structure parser->m_dtd with the root parser, so we must not destroy it */ - if (!parser->m_isParamEntity && parser->m_dtd) + if (! parser->m_isParamEntity && parser->m_dtd) #else if (parser->m_dtd) #endif /* XML_DTD */ - dtdDestroy(parser->m_dtd, (XML_Bool)!parser->m_parentParser, &parser->m_mem); + dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser, + &parser->m_mem); FREE(parser, (void *)parser->m_atts); #ifdef XML_ATTR_INFO FREE(parser, (void *)parser->m_attInfo); @@ -1440,20 +1382,19 @@ XML_ParserFree(XML_Parser parser) } void XMLCALL -XML_UseParserAsHandlerArg(XML_Parser parser) -{ +XML_UseParserAsHandlerArg(XML_Parser parser) { if (parser != NULL) parser->m_handlerArg = parser; } enum XML_Error XMLCALL -XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) -{ +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) { if (parser == NULL) return XML_ERROR_INVALID_ARGUMENT; #ifdef XML_DTD /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) + if (parser->m_parsingStatus.parsing == XML_PARSING + || parser->m_parsingStatus.parsing == XML_SUSPENDED) return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; parser->m_useForeignDTD = useDTD; return XML_ERROR_NONE; @@ -1463,19 +1404,18 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) } void XMLCALL -XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) -{ +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) { if (parser == NULL) return; /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) + if (parser->m_parsingStatus.parsing == XML_PARSING + || parser->m_parsingStatus.parsing == XML_SUSPENDED) return; parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE; } void XMLCALL -XML_SetUserData(XML_Parser parser, void *p) -{ +XML_SetUserData(XML_Parser parser, void *p) { if (parser == NULL) return; if (parser->m_handlerArg == parser->m_userData) @@ -1485,49 +1425,43 @@ XML_SetUserData(XML_Parser parser, void *p) } enum XML_Status XMLCALL -XML_SetBase(XML_Parser parser, const XML_Char *p) -{ +XML_SetBase(XML_Parser parser, const XML_Char *p) { if (parser == NULL) return XML_STATUS_ERROR; if (p) { p = poolCopyString(&parser->m_dtd->pool, p); - if (!p) + if (! p) return XML_STATUS_ERROR; parser->m_curBase = p; - } - else + } else parser->m_curBase = NULL; return XML_STATUS_OK; } -const XML_Char * XMLCALL -XML_GetBase(XML_Parser parser) -{ +const XML_Char *XMLCALL +XML_GetBase(XML_Parser parser) { if (parser == NULL) return NULL; return parser->m_curBase; } int XMLCALL -XML_GetSpecifiedAttributeCount(XML_Parser parser) -{ +XML_GetSpecifiedAttributeCount(XML_Parser parser) { if (parser == NULL) return -1; return parser->m_nSpecifiedAtts; } int XMLCALL -XML_GetIdAttributeIndex(XML_Parser parser) -{ +XML_GetIdAttributeIndex(XML_Parser parser) { if (parser == NULL) return -1; return parser->m_idAttIndex; } #ifdef XML_ATTR_INFO -const XML_AttrInfo * XMLCALL -XML_GetAttributeInfo(XML_Parser parser) -{ +const XML_AttrInfo *XMLCALL +XML_GetAttributeInfo(XML_Parser parser) { if (parser == NULL) return NULL; return parser->m_attInfo; @@ -1535,10 +1469,8 @@ XML_GetAttributeInfo(XML_Parser parser) #endif void XMLCALL -XML_SetElementHandler(XML_Parser parser, - XML_StartElementHandler start, - XML_EndElementHandler end) -{ +XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, + XML_EndElementHandler end) { if (parser == NULL) return; parser->m_startElementHandler = start; @@ -1546,39 +1478,33 @@ XML_SetElementHandler(XML_Parser parser, } void XMLCALL -XML_SetStartElementHandler(XML_Parser parser, - XML_StartElementHandler start) { +XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) { if (parser != NULL) parser->m_startElementHandler = start; } void XMLCALL -XML_SetEndElementHandler(XML_Parser parser, - XML_EndElementHandler end) { +XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) { if (parser != NULL) parser->m_endElementHandler = end; } void XMLCALL XML_SetCharacterDataHandler(XML_Parser parser, - XML_CharacterDataHandler handler) -{ + XML_CharacterDataHandler handler) { if (parser != NULL) parser->m_characterDataHandler = handler; } void XMLCALL XML_SetProcessingInstructionHandler(XML_Parser parser, - XML_ProcessingInstructionHandler handler) -{ + XML_ProcessingInstructionHandler handler) { if (parser != NULL) parser->m_processingInstructionHandler = handler; } void XMLCALL -XML_SetCommentHandler(XML_Parser parser, - XML_CommentHandler handler) -{ +XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) { if (parser != NULL) parser->m_commentHandler = handler; } @@ -1586,8 +1512,7 @@ XML_SetCommentHandler(XML_Parser parser, void XMLCALL XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, - XML_EndCdataSectionHandler end) -{ + XML_EndCdataSectionHandler end) { if (parser == NULL) return; parser->m_startCdataSectionHandler = start; @@ -1609,9 +1534,7 @@ XML_SetEndCdataSectionHandler(XML_Parser parser, } void XMLCALL -XML_SetDefaultHandler(XML_Parser parser, - XML_DefaultHandler handler) -{ +XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) { if (parser == NULL) return; parser->m_defaultHandler = handler; @@ -1619,9 +1542,7 @@ XML_SetDefaultHandler(XML_Parser parser, } void XMLCALL -XML_SetDefaultHandlerExpand(XML_Parser parser, - XML_DefaultHandler handler) -{ +XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) { if (parser == NULL) return; parser->m_defaultHandler = handler; @@ -1629,10 +1550,8 @@ XML_SetDefaultHandlerExpand(XML_Parser parser, } void XMLCALL -XML_SetDoctypeDeclHandler(XML_Parser parser, - XML_StartDoctypeDeclHandler start, - XML_EndDoctypeDeclHandler end) -{ +XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end) { if (parser == NULL) return; parser->m_startDoctypeDeclHandler = start; @@ -1647,24 +1566,20 @@ XML_SetStartDoctypeDeclHandler(XML_Parser parser, } void XMLCALL -XML_SetEndDoctypeDeclHandler(XML_Parser parser, - XML_EndDoctypeDeclHandler end) { +XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) { if (parser != NULL) parser->m_endDoctypeDeclHandler = end; } void XMLCALL XML_SetUnparsedEntityDeclHandler(XML_Parser parser, - XML_UnparsedEntityDeclHandler handler) -{ + XML_UnparsedEntityDeclHandler handler) { if (parser != NULL) parser->m_unparsedEntityDeclHandler = handler; } void XMLCALL -XML_SetNotationDeclHandler(XML_Parser parser, - XML_NotationDeclHandler handler) -{ +XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) { if (parser != NULL) parser->m_notationDeclHandler = handler; } @@ -1672,8 +1587,7 @@ XML_SetNotationDeclHandler(XML_Parser parser, void XMLCALL XML_SetNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start, - XML_EndNamespaceDeclHandler end) -{ + XML_EndNamespaceDeclHandler end) { if (parser == NULL) return; parser->m_startNamespaceDeclHandler = start; @@ -1696,23 +1610,20 @@ XML_SetEndNamespaceDeclHandler(XML_Parser parser, void XMLCALL XML_SetNotStandaloneHandler(XML_Parser parser, - XML_NotStandaloneHandler handler) -{ + XML_NotStandaloneHandler handler) { if (parser != NULL) parser->m_notStandaloneHandler = handler; } void XMLCALL XML_SetExternalEntityRefHandler(XML_Parser parser, - XML_ExternalEntityRefHandler handler) -{ + XML_ExternalEntityRefHandler handler) { if (parser != NULL) parser->m_externalEntityRefHandler = handler; } void XMLCALL -XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) -{ +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) { if (parser == NULL) return; if (arg) @@ -1723,17 +1634,14 @@ XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) void XMLCALL XML_SetSkippedEntityHandler(XML_Parser parser, - XML_SkippedEntityHandler handler) -{ + XML_SkippedEntityHandler handler) { if (parser != NULL) parser->m_skippedEntityHandler = handler; } void XMLCALL XML_SetUnknownEncodingHandler(XML_Parser parser, - XML_UnknownEncodingHandler handler, - void *data) -{ + XML_UnknownEncodingHandler handler, void *data) { if (parser == NULL) return; parser->m_unknownEncodingHandler = handler; @@ -1741,44 +1649,37 @@ XML_SetUnknownEncodingHandler(XML_Parser parser, } void XMLCALL -XML_SetElementDeclHandler(XML_Parser parser, - XML_ElementDeclHandler eldecl) -{ +XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) { if (parser != NULL) parser->m_elementDeclHandler = eldecl; } void XMLCALL -XML_SetAttlistDeclHandler(XML_Parser parser, - XML_AttlistDeclHandler attdecl) -{ +XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) { if (parser != NULL) parser->m_attlistDeclHandler = attdecl; } void XMLCALL -XML_SetEntityDeclHandler(XML_Parser parser, - XML_EntityDeclHandler handler) -{ +XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) { if (parser != NULL) parser->m_entityDeclHandler = handler; } void XMLCALL -XML_SetXmlDeclHandler(XML_Parser parser, - XML_XmlDeclHandler handler) { +XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) { if (parser != NULL) parser->m_xmlDeclHandler = handler; } int XMLCALL XML_SetParamEntityParsing(XML_Parser parser, - enum XML_ParamEntityParsing peParsing) -{ + enum XML_ParamEntityParsing peParsing) { if (parser == NULL) return 0; /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) + if (parser->m_parsingStatus.parsing == XML_PARSING + || parser->m_parsingStatus.parsing == XML_SUSPENDED) return 0; #ifdef XML_DTD parser->m_paramEntityParsing = peParsing; @@ -1789,23 +1690,21 @@ XML_SetParamEntityParsing(XML_Parser parser, } int XMLCALL -XML_SetHashSalt(XML_Parser parser, - unsigned long hash_salt) -{ +XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) { if (parser == NULL) return 0; if (parser->m_parentParser) return XML_SetHashSalt(parser->m_parentParser, hash_salt); /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) + if (parser->m_parsingStatus.parsing == XML_PARSING + || parser->m_parsingStatus.parsing == XML_SUSPENDED) return 0; parser->m_hash_secret_salt = hash_salt; return 1; } enum XML_Status XMLCALL -XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) -{ +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) { if (parser != NULL) parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; @@ -1819,7 +1718,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; case XML_INITIALIZED: - if (parser->m_parentParser == NULL && !startParsing(parser)) { + if (parser->m_parentParser == NULL && ! startParsing(parser)) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return XML_STATUS_ERROR; } @@ -1830,7 +1729,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) if (len == 0) { parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; - if (!isFinal) + if (! isFinal) return XML_STATUS_OK; parser->m_positionPtr = parser->m_bufferPtr; parser->m_parseEndPtr = parser->m_bufferEnd; @@ -1839,7 +1738,9 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) data are the final chunk of input, then we have to check them again to detect errors based on that fact. */ - parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); + parser->m_errorCode + = parser->m_processor(parser, parser->m_bufferPtr, + parser->m_parseEndPtr, &parser->m_bufferPtr); if (parser->m_errorCode == XML_ERROR_NONE) { switch (parser->m_parsingStatus.parsing) { @@ -1856,7 +1757,8 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) * * LCOV_EXCL_START */ - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, + parser->m_bufferPtr, &parser->m_position); parser->m_positionPtr = parser->m_bufferPtr; return XML_STATUS_SUSPENDED; /* LCOV_EXCL_STOP */ @@ -1879,23 +1781,23 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) enum XML_Status result; /* Detect overflow (a+b > MAX <==> b > MAX-a) */ if (len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) { - parser->m_errorCode = XML_ERROR_NO_MEMORY; - parser->m_eventPtr = parser->m_eventEndPtr = NULL; - parser->m_processor = errorProcessor; - return XML_STATUS_ERROR; + parser->m_errorCode = XML_ERROR_NO_MEMORY; + parser->m_eventPtr = parser->m_eventEndPtr = NULL; + parser->m_processor = errorProcessor; + return XML_STATUS_ERROR; } parser->m_parseEndByteIndex += len; parser->m_positionPtr = s; parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; - parser->m_errorCode = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end); + parser->m_errorCode + = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end); if (parser->m_errorCode != XML_ERROR_NONE) { parser->m_eventEndPtr = parser->m_eventPtr; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; - } - else { + } else { switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: result = XML_STATUS_SUSPENDED; @@ -1912,10 +1814,12 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) } } - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, &parser->m_position); + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, + &parser->m_position); nLeftOver = s + len - end; if (nLeftOver) { - if (parser->m_buffer == NULL || nLeftOver > parser->m_bufferLim - parser->m_buffer) { + if (parser->m_buffer == NULL + || nLeftOver > parser->m_bufferLim - parser->m_buffer) { /* avoid _signed_ integer overflow */ char *temp = NULL; const int bytesToAllocate = (int)((unsigned)len * 2U); @@ -1941,7 +1845,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) parser->m_eventEndPtr = parser->m_bufferPtr; return result; } -#endif /* not defined XML_CONTEXT_BYTES */ +#endif /* not defined XML_CONTEXT_BYTES */ else { void *buff = XML_GetBuffer(parser, len); if (buff == NULL) @@ -1954,8 +1858,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) } enum XML_Status XMLCALL -XML_ParseBuffer(XML_Parser parser, int len, int isFinal) -{ +XML_ParseBuffer(XML_Parser parser, int len, int isFinal) { const char *start; enum XML_Status result = XML_STATUS_OK; @@ -1969,7 +1872,7 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; case XML_INITIALIZED: - if (parser->m_parentParser == NULL && !startParsing(parser)) { + if (parser->m_parentParser == NULL && ! startParsing(parser)) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return XML_STATUS_ERROR; } @@ -1985,14 +1888,14 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) parser->m_parseEndByteIndex += len; parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; - parser->m_errorCode = parser->m_processor(parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr); + parser->m_errorCode = parser->m_processor( + parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr); if (parser->m_errorCode != XML_ERROR_NONE) { parser->m_eventEndPtr = parser->m_eventPtr; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; - } - else { + } else { switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: result = XML_STATUS_SUSPENDED; @@ -2003,18 +1906,18 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) parser->m_parsingStatus.parsing = XML_FINISHED; return result; } - default: ; /* should not happen */ + default:; /* should not happen */ } } - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, + parser->m_bufferPtr, &parser->m_position); parser->m_positionPtr = parser->m_bufferPtr; return result; } -void * XMLCALL -XML_GetBuffer(XML_Parser parser, int len) -{ +void *XMLCALL +XML_GetBuffer(XML_Parser parser, int len) { if (parser == NULL) return NULL; if (len < 0) { @@ -2028,17 +1931,17 @@ XML_GetBuffer(XML_Parser parser, int len) case XML_FINISHED: parser->m_errorCode = XML_ERROR_FINISHED; return NULL; - default: ; + default:; } if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) { #ifdef XML_CONTEXT_BYTES int keep; -#endif /* defined XML_CONTEXT_BYTES */ +#endif /* defined XML_CONTEXT_BYTES */ /* Do not invoke signed arithmetic overflow: */ - int neededSize = (int) ((unsigned)len + - (unsigned)EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, - parser->m_bufferPtr)); + int neededSize = (int)((unsigned)len + + (unsigned)EXPAT_SAFE_PTR_DIFF( + parser->m_bufferEnd, parser->m_bufferPtr)); if (neededSize < 0) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; @@ -2048,13 +1951,18 @@ XML_GetBuffer(XML_Parser parser, int len) if (keep > XML_CONTEXT_BYTES) keep = XML_CONTEXT_BYTES; neededSize += keep; -#endif /* defined XML_CONTEXT_BYTES */ - if (neededSize <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) { +#endif /* defined XML_CONTEXT_BYTES */ + if (neededSize + <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) { #ifdef XML_CONTEXT_BYTES if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) { - int offset = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer) - keep; - /* The buffer pointers cannot be NULL here; we have at least some bytes in the buffer */ - memmove(parser->m_buffer, &parser->m_buffer[offset], parser->m_bufferEnd - parser->m_bufferPtr + keep); + int offset + = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer) + - keep; + /* The buffer pointers cannot be NULL here; we have at least some bytes + * in the buffer */ + memmove(parser->m_buffer, &parser->m_buffer[offset], + parser->m_bufferEnd - parser->m_bufferPtr + keep); parser->m_bufferEnd -= offset; parser->m_bufferPtr -= offset; } @@ -2062,20 +1970,21 @@ XML_GetBuffer(XML_Parser parser, int len) if (parser->m_buffer && parser->m_bufferPtr) { memmove(parser->m_buffer, parser->m_bufferPtr, EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); - parser->m_bufferEnd = parser->m_buffer + - EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); + parser->m_bufferEnd + = parser->m_buffer + + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); parser->m_bufferPtr = parser->m_buffer; } -#endif /* not defined XML_CONTEXT_BYTES */ - } - else { +#endif /* not defined XML_CONTEXT_BYTES */ + } else { char *newBuf; - int bufferSize = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr); + int bufferSize + = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr); if (bufferSize == 0) bufferSize = INIT_BUFFER_SIZE; do { /* Do not invoke signed arithmetic overflow: */ - bufferSize = (int) (2U * (unsigned) bufferSize); + bufferSize = (int)(2U * (unsigned)bufferSize); } while (bufferSize < neededSize && bufferSize > 0); if (bufferSize <= 0) { parser->m_errorCode = XML_ERROR_NO_MEMORY; @@ -2089,18 +1998,17 @@ XML_GetBuffer(XML_Parser parser, int len) parser->m_bufferLim = newBuf + bufferSize; #ifdef XML_CONTEXT_BYTES if (parser->m_bufferPtr) { - int keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer); - if (keep > XML_CONTEXT_BYTES) - keep = XML_CONTEXT_BYTES; memcpy(newBuf, &parser->m_bufferPtr[-keep], - EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) + keep); + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) + + keep); FREE(parser, parser->m_buffer); parser->m_buffer = newBuf; - parser->m_bufferEnd = parser->m_buffer + - EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) + keep; + parser->m_bufferEnd + = parser->m_buffer + + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) + + keep; parser->m_bufferPtr = parser->m_buffer + keep; - } - else { + } else { /* This must be a brand new buffer with no data in it yet */ parser->m_bufferEnd = newBuf; parser->m_bufferPtr = parser->m_buffer = newBuf; @@ -2110,15 +2018,15 @@ XML_GetBuffer(XML_Parser parser, int len) memcpy(newBuf, parser->m_bufferPtr, EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); FREE(parser, parser->m_buffer); - parser->m_bufferEnd = newBuf + - EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); - } - else { + parser->m_bufferEnd + = newBuf + + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); + } else { /* This must be a brand new buffer with no data in it yet */ parser->m_bufferEnd = newBuf; } parser->m_bufferPtr = parser->m_buffer = newBuf; -#endif /* not defined XML_CONTEXT_BYTES */ +#endif /* not defined XML_CONTEXT_BYTES */ } parser->m_eventPtr = parser->m_eventEndPtr = NULL; parser->m_positionPtr = NULL; @@ -2127,8 +2035,7 @@ XML_GetBuffer(XML_Parser parser, int len) } enum XML_Status XMLCALL -XML_StopParser(XML_Parser parser, XML_Bool resumable) -{ +XML_StopParser(XML_Parser parser, XML_Bool resumable) { if (parser == NULL) return XML_STATUS_ERROR; switch (parser->m_parsingStatus.parsing) { @@ -2151,16 +2058,14 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) } #endif parser->m_parsingStatus.parsing = XML_SUSPENDED; - } - else + } else parser->m_parsingStatus.parsing = XML_FINISHED; } return XML_STATUS_OK; } enum XML_Status XMLCALL -XML_ResumeParser(XML_Parser parser) -{ +XML_ResumeParser(XML_Parser parser) { enum XML_Status result = XML_STATUS_OK; if (parser == NULL) @@ -2171,14 +2076,14 @@ XML_ResumeParser(XML_Parser parser) } parser->m_parsingStatus.parsing = XML_PARSING; - parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); + parser->m_errorCode = parser->m_processor( + parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); if (parser->m_errorCode != XML_ERROR_NONE) { parser->m_eventEndPtr = parser->m_eventPtr; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; - } - else { + } else { switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: result = XML_STATUS_SUSPENDED; @@ -2189,18 +2094,18 @@ XML_ResumeParser(XML_Parser parser) parser->m_parsingStatus.parsing = XML_FINISHED; return result; } - default: ; + default:; } } - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, + parser->m_bufferPtr, &parser->m_position); parser->m_positionPtr = parser->m_bufferPtr; return result; } void XMLCALL -XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) -{ +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) { if (parser == NULL) return; assert(status != NULL); @@ -2208,26 +2113,24 @@ XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) } enum XML_Error XMLCALL -XML_GetErrorCode(XML_Parser parser) -{ +XML_GetErrorCode(XML_Parser parser) { if (parser == NULL) return XML_ERROR_INVALID_ARGUMENT; return parser->m_errorCode; } XML_Index XMLCALL -XML_GetCurrentByteIndex(XML_Parser parser) -{ +XML_GetCurrentByteIndex(XML_Parser parser) { if (parser == NULL) return -1; if (parser->m_eventPtr) - return (XML_Index)(parser->m_parseEndByteIndex - (parser->m_parseEndPtr - parser->m_eventPtr)); + return (XML_Index)(parser->m_parseEndByteIndex + - (parser->m_parseEndPtr - parser->m_eventPtr)); return -1; } int XMLCALL -XML_GetCurrentByteCount(XML_Parser parser) -{ +XML_GetCurrentByteCount(XML_Parser parser) { if (parser == NULL) return 0; if (parser->m_eventEndPtr && parser->m_eventPtr) @@ -2235,9 +2138,8 @@ XML_GetCurrentByteCount(XML_Parser parser) return 0; } -const char * XMLCALL -XML_GetInputContext(XML_Parser parser, int *offset, int *size) -{ +const char *XMLCALL +XML_GetInputContext(XML_Parser parser, int *offset, int *size) { #ifdef XML_CONTEXT_BYTES if (parser == NULL) return NULL; @@ -2245,7 +2147,7 @@ XML_GetInputContext(XML_Parser parser, int *offset, int *size) if (offset != NULL) *offset = (int)(parser->m_eventPtr - parser->m_buffer); if (size != NULL) - *size = (int)(parser->m_bufferEnd - parser->m_buffer); + *size = (int)(parser->m_bufferEnd - parser->m_buffer); return parser->m_buffer; } #else @@ -2253,82 +2155,76 @@ XML_GetInputContext(XML_Parser parser, int *offset, int *size) (void)offset; (void)size; #endif /* defined XML_CONTEXT_BYTES */ - return (char *) 0; + return (char *)0; } XML_Size XMLCALL -XML_GetCurrentLineNumber(XML_Parser parser) -{ +XML_GetCurrentLineNumber(XML_Parser parser) { if (parser == NULL) return 0; if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position); + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, + parser->m_eventPtr, &parser->m_position); parser->m_positionPtr = parser->m_eventPtr; } return parser->m_position.lineNumber + 1; } XML_Size XMLCALL -XML_GetCurrentColumnNumber(XML_Parser parser) -{ +XML_GetCurrentColumnNumber(XML_Parser parser) { if (parser == NULL) return 0; if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position); + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, + parser->m_eventPtr, &parser->m_position); parser->m_positionPtr = parser->m_eventPtr; } return parser->m_position.columnNumber; } void XMLCALL -XML_FreeContentModel(XML_Parser parser, XML_Content *model) -{ +XML_FreeContentModel(XML_Parser parser, XML_Content *model) { if (parser != NULL) FREE(parser, model); } -void * XMLCALL -XML_MemMalloc(XML_Parser parser, size_t size) -{ +void *XMLCALL +XML_MemMalloc(XML_Parser parser, size_t size) { if (parser == NULL) return NULL; return MALLOC(parser, size); } -void * XMLCALL -XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) -{ +void *XMLCALL +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) { if (parser == NULL) return NULL; return REALLOC(parser, ptr, size); } void XMLCALL -XML_MemFree(XML_Parser parser, void *ptr) -{ +XML_MemFree(XML_Parser parser, void *ptr) { if (parser != NULL) FREE(parser, ptr); } void XMLCALL -XML_DefaultCurrent(XML_Parser parser) -{ +XML_DefaultCurrent(XML_Parser parser) { if (parser == NULL) return; if (parser->m_defaultHandler) { if (parser->m_openInternalEntities) - reportDefault(parser, - parser->m_internalEncoding, + reportDefault(parser, parser->m_internalEncoding, parser->m_openInternalEntities->internalEventPtr, parser->m_openInternalEntities->internalEventEndPtr); else - reportDefault(parser, parser->m_encoding, parser->m_eventPtr, parser->m_eventEndPtr); + reportDefault(parser, parser->m_encoding, parser->m_eventPtr, + parser->m_eventEndPtr); } } -const XML_LChar * XMLCALL -XML_ErrorString(enum XML_Error code) -{ +const XML_LChar *XMLCALL +XML_ErrorString(enum XML_Error code) { switch (code) { case XML_ERROR_NONE: return NULL; @@ -2410,21 +2306,22 @@ XML_ErrorString(enum XML_Error code) return XML_L("cannot suspend in external parameter entity"); /* Added in 2.0.0. */ case XML_ERROR_RESERVED_PREFIX_XML: - return XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"); + return XML_L( + "reserved prefix (xml) must not be undeclared or bound to another namespace name"); case XML_ERROR_RESERVED_PREFIX_XMLNS: return XML_L("reserved prefix (xmlns) must not be declared or undeclared"); case XML_ERROR_RESERVED_NAMESPACE_URI: - return XML_L("prefix must not be bound to one of the reserved namespace names"); + return XML_L( + "prefix must not be bound to one of the reserved namespace names"); /* Added in 2.2.5. */ - case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */ + case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */ return XML_L("invalid argument"); } return NULL; } -const XML_LChar * XMLCALL +const XML_LChar *XMLCALL XML_ExpatVersion(void) { - /* V1 is used to string-ize the version number. However, it would string-ize the actual version macro *names* unless we get them substituted before being passed to V1. CPP is defined to expand @@ -2433,8 +2330,8 @@ XML_ExpatVersion(void) { with the correct numerals. */ /* ### I'm assuming cpp is portable in this respect... */ -#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c) -#define V2(a,b,c) XML_L("expat_")V1(a,b,c) +#define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c) +#define V2(a, b, c) XML_L("expat_") V1(a, b, c) return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); @@ -2443,8 +2340,7 @@ XML_ExpatVersion(void) { } XML_Expat_Version XMLCALL -XML_ExpatVersionInfo(void) -{ +XML_ExpatVersionInfo(void) { XML_Expat_Version version; version.major = XML_MAJOR_VERSION; @@ -2454,41 +2350,39 @@ XML_ExpatVersionInfo(void) return version; } -const XML_Feature * XMLCALL -XML_GetFeatureList(void) -{ - static const XML_Feature features[] = { - {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), - sizeof(XML_Char)}, - {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), - sizeof(XML_LChar)}, +const XML_Feature *XMLCALL +XML_GetFeatureList(void) { + static const XML_Feature features[] + = {{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), + sizeof(XML_Char)}, + {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), + sizeof(XML_LChar)}, #ifdef XML_UNICODE - {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, + {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, #endif #ifdef XML_UNICODE_WCHAR_T - {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, + {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, #endif #ifdef XML_DTD - {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, + {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, #endif #ifdef XML_CONTEXT_BYTES - {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), - XML_CONTEXT_BYTES}, + {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), + XML_CONTEXT_BYTES}, #endif #ifdef XML_MIN_SIZE - {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, + {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, #endif #ifdef XML_NS - {XML_FEATURE_NS, XML_L("XML_NS"), 0}, + {XML_FEATURE_NS, XML_L("XML_NS"), 0}, #endif #ifdef XML_LARGE_SIZE - {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, + {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, #endif #ifdef XML_ATTR_INFO - {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0}, + {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0}, #endif - {XML_FEATURE_END, NULL, 0} - }; + {XML_FEATURE_END, NULL, 0}}; return features; } @@ -2499,8 +2393,7 @@ XML_GetFeatureList(void) permanent location, since the parse buffer is about to be discarded. */ static XML_Bool -storeRawNames(XML_Parser parser) -{ +storeRawNames(XML_Parser parser) { TAG *tag = parser->m_tagStack; while (tag) { int bufSize; @@ -2530,8 +2423,8 @@ storeRawNames(XML_Parser parser) then update it as well, since it will always point into tag->buf */ if (tag->name.localPart) - tag->name.localPart = (XML_Char *)temp + (tag->name.localPart - - (XML_Char *)tag->buf); + tag->name.localPart + = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf); tag->buf = temp; tag->bufEnd = temp + bufSize; rawNameBuf = temp + nameLen; @@ -2544,26 +2437,21 @@ storeRawNames(XML_Parser parser) } static enum XML_Error PTRCALL -contentProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = doContent(parser, 0, parser->m_encoding, start, end, - endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); +contentProcessor(XML_Parser parser, const char *start, const char *end, + const char **endPtr) { + enum XML_Error result + = doContent(parser, 0, parser->m_encoding, start, end, endPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer); if (result == XML_ERROR_NONE) { - if (!storeRawNames(parser)) + if (! storeRawNames(parser)) return XML_ERROR_NO_MEMORY; } return result; } static enum XML_Error PTRCALL -externalEntityInitProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ +externalEntityInitProcessor(XML_Parser parser, const char *start, + const char *end, const char **endPtr) { enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; @@ -2572,11 +2460,8 @@ externalEntityInitProcessor(XML_Parser parser, } static enum XML_Error PTRCALL -externalEntityInitProcessor2(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ +externalEntityInitProcessor2(XML_Parser parser, const char *start, + const char *end, const char **endPtr) { const char *next = start; /* XmlContentTok doesn't always set the last arg */ int tok = XmlContentTok(parser->m_encoding, start, end, &next); switch (tok) { @@ -2586,21 +2471,21 @@ externalEntityInitProcessor2(XML_Parser parser, doContent (by detecting XML_TOK_NONE) without processing any xml text declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. */ - if (next == end && !parser->m_parsingStatus.finalBuffer) { + if (next == end && ! parser->m_parsingStatus.finalBuffer) { *endPtr = next; return XML_ERROR_NONE; } start = next; break; case XML_TOK_PARTIAL: - if (!parser->m_parsingStatus.finalBuffer) { + if (! parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } parser->m_eventPtr = start; return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: - if (!parser->m_parsingStatus.finalBuffer) { + if (! parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } @@ -2612,11 +2497,8 @@ externalEntityInitProcessor2(XML_Parser parser, } static enum XML_Error PTRCALL -externalEntityInitProcessor3(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ +externalEntityInitProcessor3(XML_Parser parser, const char *start, + const char *end, const char **endPtr) { int tok; const char *next = start; /* XmlContentTok doesn't always set the last arg */ parser->m_eventPtr = start; @@ -2624,31 +2506,29 @@ externalEntityInitProcessor3(XML_Parser parser, parser->m_eventEndPtr = next; switch (tok) { - case XML_TOK_XML_DECL: - { - enum XML_Error result; - result = processXmlDecl(parser, 1, start, next); - if (result != XML_ERROR_NONE) - return result; - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - *endPtr = next; - return XML_ERROR_NONE; - case XML_FINISHED: - return XML_ERROR_ABORTED; - default: - start = next; - } + case XML_TOK_XML_DECL: { + enum XML_Error result; + result = processXmlDecl(parser, 1, start, next); + if (result != XML_ERROR_NONE) + return result; + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + *endPtr = next; + return XML_ERROR_NONE; + case XML_FINISHED: + return XML_ERROR_ABORTED; + default: + start = next; } - break; + } break; case XML_TOK_PARTIAL: - if (!parser->m_parsingStatus.finalBuffer) { + if (! parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: - if (!parser->m_parsingStatus.finalBuffer) { + if (! parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } @@ -2660,39 +2540,31 @@ externalEntityInitProcessor3(XML_Parser parser, } static enum XML_Error PTRCALL -externalEntityContentProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = doContent(parser, 1, parser->m_encoding, start, end, - endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); +externalEntityContentProcessor(XML_Parser parser, const char *start, + const char *end, const char **endPtr) { + enum XML_Error result + = doContent(parser, 1, parser->m_encoding, start, end, endPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer); if (result == XML_ERROR_NONE) { - if (!storeRawNames(parser)) + if (! storeRawNames(parser)) return XML_ERROR_NO_MEMORY; } return result; } static enum XML_Error -doContent(XML_Parser parser, - int startTagLevel, - const ENCODING *enc, - const char *s, - const char *end, - const char **nextPtr, - XML_Bool haveMore) -{ +doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, + const char *s, const char *end, const char **nextPtr, + XML_Bool haveMore) { /* save one level of indirection */ - DTD * const dtd = parser->m_dtd; + DTD *const dtd = parser->m_dtd; const char **eventPP; const char **eventEndPP; if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; eventEndPP = &parser->m_eventEndPtr; - } - else { + } else { eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); } @@ -2712,8 +2584,7 @@ doContent(XML_Parser parser, if (parser->m_characterDataHandler) { XML_Char c = 0xA; parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); - } - else if (parser->m_defaultHandler) + } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, end); /* We are at the end of the final buffer, should we check for XML_SUSPENDED, XML_FINISHED? @@ -2751,185 +2622,178 @@ doContent(XML_Parser parser, return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_ENTITY_REF: - { - const XML_Char *name; - ENTITY *entity; - XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (ch) { - if (parser->m_characterDataHandler) - parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1); - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - break; - } - name = poolStoreString(&dtd->pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) - return XML_ERROR_NO_MEMORY; - entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); - poolDiscard(&dtd->pool); - /* First, determine if a check for an existing declaration is needed; - if yes, check that the entity exists, and that it is internal, - otherwise call the skipped entity or default handler. - */ - if (!dtd->hasParamEntityRefs || dtd->standalone) { - if (!entity) - return XML_ERROR_UNDEFINED_ENTITY; - else if (!entity->is_internal) - return XML_ERROR_ENTITY_DECLARED_IN_PE; - } - else if (!entity) { + case XML_TOK_ENTITY_REF: { + const XML_Char *name; + ENTITY *entity; + XML_Char ch = (XML_Char)XmlPredefinedEntityName( + enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); + if (ch) { + if (parser->m_characterDataHandler) + parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1); + else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); + poolDiscard(&dtd->pool); + /* First, determine if a check for an existing declaration is needed; + if yes, check that the entity exists, and that it is internal, + otherwise call the skipped entity or default handler. + */ + if (! dtd->hasParamEntityRefs || dtd->standalone) { + if (! entity) + return XML_ERROR_UNDEFINED_ENTITY; + else if (! entity->is_internal) + return XML_ERROR_ENTITY_DECLARED_IN_PE; + } else if (! entity) { + if (parser->m_skippedEntityHandler) + parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); + else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + if (entity->open) + return XML_ERROR_RECURSIVE_ENTITY_REF; + if (entity->notation) + return XML_ERROR_BINARY_ENTITY_REF; + if (entity->textPtr) { + enum XML_Error result; + if (! parser->m_defaultExpandInternalEntities) { if (parser->m_skippedEntityHandler) - parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); + parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, + 0); else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } - if (entity->open) - return XML_ERROR_RECURSIVE_ENTITY_REF; - if (entity->notation) - return XML_ERROR_BINARY_ENTITY_REF; - if (entity->textPtr) { - enum XML_Error result; - if (!parser->m_defaultExpandInternalEntities) { - if (parser->m_skippedEntityHandler) - parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, 0); - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - break; - } - result = processInternalEntity(parser, entity, XML_FALSE); - if (result != XML_ERROR_NONE) - return result; - } - else if (parser->m_externalEntityRefHandler) { - const XML_Char *context; - entity->open = XML_TRUE; - context = getContext(parser); - entity->open = XML_FALSE; - if (!context) - return XML_ERROR_NO_MEMORY; - if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, - context, - entity->base, - entity->systemId, - entity->publicId)) - return XML_ERROR_EXTERNAL_ENTITY_HANDLING; - poolDiscard(&parser->m_tempPool); - } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - break; - } + result = processInternalEntity(parser, entity, XML_FALSE); + if (result != XML_ERROR_NONE) + return result; + } else if (parser->m_externalEntityRefHandler) { + const XML_Char *context; + entity->open = XML_TRUE; + context = getContext(parser); + entity->open = XML_FALSE; + if (! context) + return XML_ERROR_NO_MEMORY; + if (! parser->m_externalEntityRefHandler( + parser->m_externalEntityRefHandlerArg, context, entity->base, + entity->systemId, entity->publicId)) + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + poolDiscard(&parser->m_tempPool); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + break; + } case XML_TOK_START_TAG_NO_ATTS: /* fall through */ - case XML_TOK_START_TAG_WITH_ATTS: - { - TAG *tag; - enum XML_Error result; - XML_Char *toPtr; - if (parser->m_freeTagList) { - tag = parser->m_freeTagList; - parser->m_freeTagList = parser->m_freeTagList->parent; + case XML_TOK_START_TAG_WITH_ATTS: { + TAG *tag; + enum XML_Error result; + XML_Char *toPtr; + if (parser->m_freeTagList) { + tag = parser->m_freeTagList; + parser->m_freeTagList = parser->m_freeTagList->parent; + } else { + tag = (TAG *)MALLOC(parser, sizeof(TAG)); + if (! tag) + return XML_ERROR_NO_MEMORY; + tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE); + if (! tag->buf) { + FREE(parser, tag); + return XML_ERROR_NO_MEMORY; } - else { - tag = (TAG *)MALLOC(parser, sizeof(TAG)); - if (!tag) - return XML_ERROR_NO_MEMORY; - tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE); - if (!tag->buf) { - FREE(parser, tag); - return XML_ERROR_NO_MEMORY; + tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; + } + tag->bindings = NULL; + tag->parent = parser->m_tagStack; + parser->m_tagStack = tag; + tag->name.localPart = NULL; + tag->name.prefix = NULL; + tag->rawName = s + enc->minBytesPerChar; + tag->rawNameLength = XmlNameLength(enc, tag->rawName); + ++parser->m_tagLevel; + { + const char *rawNameEnd = tag->rawName + tag->rawNameLength; + const char *fromPtr = tag->rawName; + toPtr = (XML_Char *)tag->buf; + for (;;) { + int bufSize; + int convLen; + const enum XML_Convert_Result convert_res + = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr, + (ICHAR *)tag->bufEnd - 1); + convLen = (int)(toPtr - (XML_Char *)tag->buf); + if ((fromPtr >= rawNameEnd) + || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { + tag->name.strLen = convLen; + break; } - tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; - } - tag->bindings = NULL; - tag->parent = parser->m_tagStack; - parser->m_tagStack = tag; - tag->name.localPart = NULL; - tag->name.prefix = NULL; - tag->rawName = s + enc->minBytesPerChar; - tag->rawNameLength = XmlNameLength(enc, tag->rawName); - ++parser->m_tagLevel; - { - const char *rawNameEnd = tag->rawName + tag->rawNameLength; - const char *fromPtr = tag->rawName; - toPtr = (XML_Char *)tag->buf; - for (;;) { - int bufSize; - int convLen; - const enum XML_Convert_Result convert_res = XmlConvert(enc, - &fromPtr, rawNameEnd, - (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); - convLen = (int)(toPtr - (XML_Char *)tag->buf); - if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { - tag->name.strLen = convLen; - break; - } - bufSize = (int)(tag->bufEnd - tag->buf) << 1; - { - char *temp = (char *)REALLOC(parser, tag->buf, bufSize); - if (temp == NULL) - return XML_ERROR_NO_MEMORY; - tag->buf = temp; - tag->bufEnd = temp + bufSize; - toPtr = (XML_Char *)temp + convLen; - } + bufSize = (int)(tag->bufEnd - tag->buf) << 1; + { + char *temp = (char *)REALLOC(parser, tag->buf, bufSize); + if (temp == NULL) + return XML_ERROR_NO_MEMORY; + tag->buf = temp; + tag->bufEnd = temp + bufSize; + toPtr = (XML_Char *)temp + convLen; } } - tag->name.str = (XML_Char *)tag->buf; - *toPtr = XML_T('\0'); - result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); - if (result) - return result; - if (parser->m_startElementHandler) - parser->m_startElementHandler(parser->m_handlerArg, tag->name.str, - (const XML_Char **)parser->m_atts); - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - poolClear(&parser->m_tempPool); - break; } + tag->name.str = (XML_Char *)tag->buf; + *toPtr = XML_T('\0'); + result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); + if (result) + return result; + if (parser->m_startElementHandler) + parser->m_startElementHandler(parser->m_handlerArg, tag->name.str, + (const XML_Char **)parser->m_atts); + else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + poolClear(&parser->m_tempPool); + break; + } case XML_TOK_EMPTY_ELEMENT_NO_ATTS: /* fall through */ - case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: - { - const char *rawName = s + enc->minBytesPerChar; - enum XML_Error result; - BINDING *bindings = NULL; - XML_Bool noElmHandlers = XML_TRUE; - TAG_NAME name; - name.str = poolStoreString(&parser->m_tempPool, enc, rawName, - rawName + XmlNameLength(enc, rawName)); - if (!name.str) - return XML_ERROR_NO_MEMORY; - poolFinish(&parser->m_tempPool); - result = storeAtts(parser, enc, s, &name, &bindings); - if (result != XML_ERROR_NONE) { - freeBindings(parser, bindings); - return result; - } - poolFinish(&parser->m_tempPool); - if (parser->m_startElementHandler) { - parser->m_startElementHandler(parser->m_handlerArg, name.str, (const XML_Char **)parser->m_atts); - noElmHandlers = XML_FALSE; - } - if (parser->m_endElementHandler) { - if (parser->m_startElementHandler) - *eventPP = *eventEndPP; - parser->m_endElementHandler(parser->m_handlerArg, name.str); - noElmHandlers = XML_FALSE; - } - if (noElmHandlers && parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - poolClear(&parser->m_tempPool); + case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: { + const char *rawName = s + enc->minBytesPerChar; + enum XML_Error result; + BINDING *bindings = NULL; + XML_Bool noElmHandlers = XML_TRUE; + TAG_NAME name; + name.str = poolStoreString(&parser->m_tempPool, enc, rawName, + rawName + XmlNameLength(enc, rawName)); + if (! name.str) + return XML_ERROR_NO_MEMORY; + poolFinish(&parser->m_tempPool); + result = storeAtts(parser, enc, s, &name, &bindings); + if (result != XML_ERROR_NONE) { freeBindings(parser, bindings); + return result; } - if ((parser->m_tagLevel == 0) && (parser->m_parsingStatus.parsing != XML_FINISHED)) { + poolFinish(&parser->m_tempPool); + if (parser->m_startElementHandler) { + parser->m_startElementHandler(parser->m_handlerArg, name.str, + (const XML_Char **)parser->m_atts); + noElmHandlers = XML_FALSE; + } + if (parser->m_endElementHandler) { + if (parser->m_startElementHandler) + *eventPP = *eventEndPP; + parser->m_endElementHandler(parser->m_handlerArg, name.str); + noElmHandlers = XML_FALSE; + } + if (noElmHandlers && parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + poolClear(&parser->m_tempPool); + freeBindings(parser, bindings); + } + if ((parser->m_tagLevel == 0) + && (parser->m_parsingStatus.parsing != XML_FINISHED)) { if (parser->m_parsingStatus.parsing == XML_SUSPENDED) parser->m_processor = epilogProcessor; else @@ -2946,7 +2810,7 @@ doContent(XML_Parser parser, parser->m_tagStack = tag->parent; tag->parent = parser->m_freeTagList; parser->m_freeTagList = tag; - rawName = s + enc->minBytesPerChar*2; + rawName = s + enc->minBytesPerChar * 2; len = XmlNameLength(enc, rawName); if (len != tag->rawNameLength || memcmp(tag->rawName, rawName, len) != 0) { @@ -2966,86 +2830,89 @@ doContent(XML_Parser parser, */ uri = (XML_Char *)tag->name.str + tag->name.uriLen; /* don't need to check for space - already done in storeAtts() */ - while (*localPart) *uri++ = *localPart++; + while (*localPart) + *uri++ = *localPart++; prefix = (XML_Char *)tag->name.prefix; if (parser->m_ns_triplets && prefix) { *uri++ = parser->m_namespaceSeparator; - while (*prefix) *uri++ = *prefix++; - } + while (*prefix) + *uri++ = *prefix++; + } *uri = XML_T('\0'); } parser->m_endElementHandler(parser->m_handlerArg, tag->name.str); - } - else if (parser->m_defaultHandler) + } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); while (tag->bindings) { BINDING *b = tag->bindings; if (parser->m_endNamespaceDeclHandler) - parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); + parser->m_endNamespaceDeclHandler(parser->m_handlerArg, + b->prefix->name); tag->bindings = tag->bindings->nextTagBinding; b->nextTagBinding = parser->m_freeBindingList; parser->m_freeBindingList = b; b->prefix->binding = b->prevPrefixBinding; } - if (parser->m_tagLevel == 0) - return epilogProcessor(parser, next, end, nextPtr); - } - break; - case XML_TOK_CHAR_REF: - { - int n = XmlCharRefNumber(enc, s); - if (n < 0) - return XML_ERROR_BAD_CHAR_REF; - if (parser->m_characterDataHandler) { - XML_Char buf[XML_ENCODE_MAX]; - parser->m_characterDataHandler(parser->m_handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); + if ((parser->m_tagLevel == 0) + && (parser->m_parsingStatus.parsing != XML_FINISHED)) { + if (parser->m_parsingStatus.parsing == XML_SUSPENDED) + parser->m_processor = epilogProcessor; + else + return epilogProcessor(parser, next, end, nextPtr); } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); } break; + case XML_TOK_CHAR_REF: { + int n = XmlCharRefNumber(enc, s); + if (n < 0) + return XML_ERROR_BAD_CHAR_REF; + if (parser->m_characterDataHandler) { + XML_Char buf[XML_ENCODE_MAX]; + parser->m_characterDataHandler(parser->m_handlerArg, buf, + XmlEncode(n, (ICHAR *)buf)); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + } break; case XML_TOK_XML_DECL: return XML_ERROR_MISPLACED_XML_PI; case XML_TOK_DATA_NEWLINE: if (parser->m_characterDataHandler) { XML_Char c = 0xA; parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); - } - else if (parser->m_defaultHandler) + } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; - case XML_TOK_CDATA_SECT_OPEN: - { - enum XML_Error result; - if (parser->m_startCdataSectionHandler) - parser->m_startCdataSectionHandler(parser->m_handlerArg); -#if 0 - /* Suppose you doing a transformation on a document that involves - changing only the character data. You set up a defaultHandler - and a characterDataHandler. The defaultHandler simply copies - characters through. The characterDataHandler does the - transformation and writes the characters out escaping them as - necessary. This case will fail to work if we leave out the - following two lines (because & and < inside CDATA sections will - be incorrectly escaped). - - However, now we have a start/endCdataSectionHandler, so it seems - easier to let the user deal with this. - */ - else if (parser->m_characterDataHandler) - parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0); -#endif - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore); - if (result != XML_ERROR_NONE) - return result; - else if (!next) { - parser->m_processor = cdataSectionProcessor; - return result; - } + case XML_TOK_CDATA_SECT_OPEN: { + enum XML_Error result; + if (parser->m_startCdataSectionHandler) + parser->m_startCdataSectionHandler(parser->m_handlerArg); + /* BEGIN disabled code */ + /* Suppose you doing a transformation on a document that involves + changing only the character data. You set up a defaultHandler + and a characterDataHandler. The defaultHandler simply copies + characters through. The characterDataHandler does the + transformation and writes the characters out escaping them as + necessary. This case will fail to work if we leave out the + following two lines (because & and < inside CDATA sections will + be incorrectly escaped). + + However, now we have a start/endCdataSectionHandler, so it seems + easier to let the user deal with this. + */ + else if (0 && parser->m_characterDataHandler) + parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, + 0); + /* END disabled code */ + else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore); + if (result != XML_ERROR_NONE) + return result; + else if (! next) { + parser->m_processor = cdataSectionProcessor; + return result; } - break; + } break; case XML_TOK_TRAILING_RSQB: if (haveMore) { *nextPtr = s; @@ -3055,15 +2922,14 @@ doContent(XML_Parser parser, if (MUST_CONVERT(enc, s)) { ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); - parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, - (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); - } - else - parser->m_characterDataHandler(parser->m_handlerArg, - (XML_Char *)s, - (int)((XML_Char *)end - (XML_Char *)s)); - } - else if (parser->m_defaultHandler) + parser->m_characterDataHandler( + parser->m_handlerArg, parser->m_dataBuf, + (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); + } else + parser->m_characterDataHandler( + parser->m_handlerArg, (XML_Char *)s, + (int)((XML_Char *)end - (XML_Char *)s)); + } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, end); /* We are at the end of the final buffer, should we check for XML_SUSPENDED, XML_FINISHED? @@ -3078,37 +2944,34 @@ doContent(XML_Parser parser, } *nextPtr = end; return XML_ERROR_NONE; - case XML_TOK_DATA_CHARS: - { - XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; - if (charDataHandler) { - if (MUST_CONVERT(enc, s)) { - for (;;) { - ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; - const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); - *eventEndPP = s; - charDataHandler(parser->m_handlerArg, parser->m_dataBuf, - (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); - if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) - break; - *eventPP = s; - } + case XML_TOK_DATA_CHARS: { + XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; + if (charDataHandler) { + if (MUST_CONVERT(enc, s)) { + for (;;) { + ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; + const enum XML_Convert_Result convert_res = XmlConvert( + enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); + *eventEndPP = s; + charDataHandler(parser->m_handlerArg, parser->m_dataBuf, + (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); + if ((convert_res == XML_CONVERT_COMPLETED) + || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) + break; + *eventPP = s; } - else - charDataHandler(parser->m_handlerArg, - (XML_Char *)s, - (int)((XML_Char *)next - (XML_Char *)s)); - } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - } - break; + } else + charDataHandler(parser->m_handlerArg, (XML_Char *)s, + (int)((XML_Char *)next - (XML_Char *)s)); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + } break; case XML_TOK_PI: - if (!reportProcessingInstruction(parser, enc, s, next)) + if (! reportProcessingInstruction(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_COMMENT: - if (!reportComment(parser, enc, s, next)) + if (! reportComment(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; break; default: @@ -3131,7 +2994,7 @@ doContent(XML_Parser parser, return XML_ERROR_NONE; case XML_FINISHED: return XML_ERROR_ABORTED; - default: ; + default:; } } /* not reached */ @@ -3142,8 +3005,7 @@ doContent(XML_Parser parser, * reused as appropriate. */ static void -freeBindings(XML_Parser parser, BINDING *bindings) -{ +freeBindings(XML_Parser parser, BINDING *bindings) { while (bindings) { BINDING *b = bindings; @@ -3151,7 +3013,7 @@ freeBindings(XML_Parser parser, BINDING *bindings) * binding in addBindings(), so call the end handler now. */ if (parser->m_endNamespaceDeclHandler) - parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); + parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); bindings = bindings->nextTagBinding; b->nextTagBinding = parser->m_freeBindingList; @@ -3171,14 +3033,12 @@ freeBindings(XML_Parser parser, BINDING *bindings) - generate namespace aware element name (URI, prefix) */ static enum XML_Error -storeAtts(XML_Parser parser, const ENCODING *enc, - const char *attStr, TAG_NAME *tagNamePtr, - BINDING **bindingsPtr) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ +storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, + TAG_NAME *tagNamePtr, BINDING **bindingsPtr) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ ELEMENT_TYPE *elementType; int nDefaultAtts; - const XML_Char **appAtts; /* the attribute list for the application */ + const XML_Char **appAtts; /* the attribute list for the application */ int attIndex = 0; int prefixLen; int i; @@ -3189,16 +3049,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const XML_Char *localPart; /* lookup the element type name */ - elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0); - if (!elementType) { + elementType + = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0); + if (! elementType) { const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); - if (!name) + if (! name) return XML_ERROR_NO_MEMORY; elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); - if (!elementType) + if (! elementType) return XML_ERROR_NO_MEMORY; - if (parser->m_ns && !setElementTypePrefix(parser, elementType)) + if (parser->m_ns && ! setElementTypePrefix(parser, elementType)) return XML_ERROR_NO_MEMORY; } nDefaultAtts = elementType->nDefaultAtts; @@ -3212,14 +3073,16 @@ storeAtts(XML_Parser parser, const ENCODING *enc, XML_AttrInfo *temp2; #endif parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; - temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE)); + temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, + parser->m_attsSize * sizeof(ATTRIBUTE)); if (temp == NULL) { parser->m_attsSize = oldAttsSize; return XML_ERROR_NO_MEMORY; } parser->m_atts = temp; #ifdef XML_ATTR_INFO - temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo)); + temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, + parser->m_attsSize * sizeof(XML_AttrInfo)); if (temp2 == NULL) { parser->m_attsSize = oldAttsSize; return XML_ERROR_NO_MEMORY; @@ -3237,18 +3100,20 @@ storeAtts(XML_Parser parser, const ENCODING *enc, XML_AttrInfo *currAttInfo = &parser->m_attInfo[i]; #endif /* add the name and value to the attribute list */ - ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name, - currAtt->name - + XmlNameLength(enc, currAtt->name)); - if (!attId) + ATTRIBUTE_ID *attId + = getAttributeId(parser, enc, currAtt->name, + currAtt->name + XmlNameLength(enc, currAtt->name)); + if (! attId) return XML_ERROR_NO_MEMORY; #ifdef XML_ATTR_INFO - currAttInfo->nameStart = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name); - currAttInfo->nameEnd = currAttInfo->nameStart + - XmlNameLength(enc, currAtt->name); - currAttInfo->valueStart = parser->m_parseEndByteIndex - - (parser->m_parseEndPtr - currAtt->valuePtr); - currAttInfo->valueEnd = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->valueEnd); + currAttInfo->nameStart + = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name); + currAttInfo->nameEnd + = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name); + currAttInfo->valueStart = parser->m_parseEndByteIndex + - (parser->m_parseEndPtr - currAtt->valuePtr); + currAttInfo->valueEnd = parser->m_parseEndByteIndex + - (parser->m_parseEndPtr - currAtt->valueEnd); #endif /* Detect duplicate attributes by their QNames. This does not work when namespace processing is turned on and different prefixes for the same @@ -3261,7 +3126,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, } (attId->name)[-1] = 1; appAtts[attIndex++] = attId->name; - if (!parser->m_atts[i].normalized) { + if (! parser->m_atts[i].normalized) { enum XML_Error result; XML_Bool isCdata = XML_TRUE; @@ -3277,17 +3142,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc, } /* normalize the attribute value */ - result = storeAttributeValue(parser, enc, isCdata, - parser->m_atts[i].valuePtr, parser->m_atts[i].valueEnd, - &parser->m_tempPool); + result = storeAttributeValue( + parser, enc, isCdata, parser->m_atts[i].valuePtr, + parser->m_atts[i].valueEnd, &parser->m_tempPool); if (result) return result; appAtts[attIndex] = poolStart(&parser->m_tempPool); poolFinish(&parser->m_tempPool); - } - else { + } else { /* the value did not need normalizing */ - appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, parser->m_atts[i].valuePtr, + appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, + parser->m_atts[i].valuePtr, parser->m_atts[i].valueEnd); if (appAtts[attIndex] == 0) return XML_ERROR_NO_MEMORY; @@ -3302,15 +3167,13 @@ storeAtts(XML_Parser parser, const ENCODING *enc, if (result) return result; --attIndex; - } - else { + } else { /* deal with other prefixed names later */ attIndex++; nPrefixes++; (attId->name)[-1] = 2; } - } - else + } else attIndex++; } @@ -3322,29 +3185,26 @@ storeAtts(XML_Parser parser, const ENCODING *enc, parser->m_idAttIndex = i; break; } - } - else + } else parser->m_idAttIndex = -1; /* do attribute defaulting */ for (i = 0; i < nDefaultAtts; i++) { const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; - if (!(da->id->name)[-1] && da->value) { + if (! (da->id->name)[-1] && da->value) { if (da->id->prefix) { if (da->id->xmlns) { enum XML_Error result = addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr); if (result) return result; - } - else { + } else { (da->id->name)[-1] = 2; nPrefixes++; appAtts[attIndex++] = da->id->name; appAtts[attIndex++] = da->value; } - } - else { + } else { (da->id->name)[-1] = 1; appAtts[attIndex++] = da->id->name; appAtts[attIndex++] = da->value; @@ -3357,31 +3217,34 @@ storeAtts(XML_Parser parser, const ENCODING *enc, and clear flags that say whether attributes were specified */ i = 0; if (nPrefixes) { - int j; /* hash table index */ + int j; /* hash table index */ unsigned long version = parser->m_nsAttsVersion; int nsAttsSize = (int)1 << parser->m_nsAttsPower; unsigned char oldNsAttsPower = parser->m_nsAttsPower; /* size of hash table must be at least 2 * (# of prefixed attributes) */ - if ((nPrefixes << 1) >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */ + if ((nPrefixes << 1) + >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */ NS_ATT *temp; /* hash table size must also be a power of 2 and >= 8 */ - while (nPrefixes >> parser->m_nsAttsPower++); + while (nPrefixes >> parser->m_nsAttsPower++) + ; if (parser->m_nsAttsPower < 3) parser->m_nsAttsPower = 3; nsAttsSize = (int)1 << parser->m_nsAttsPower; - temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT)); - if (!temp) { + temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, + nsAttsSize * sizeof(NS_ATT)); + if (! temp) { /* Restore actual size of memory in m_nsAtts */ parser->m_nsAttsPower = oldNsAttsPower; return XML_ERROR_NO_MEMORY; } parser->m_nsAtts = temp; - version = 0; /* force re-initialization of m_nsAtts hash table */ + version = 0; /* force re-initialization of m_nsAtts hash table */ } /* using a version flag saves us from initializing m_nsAtts every time */ - if (!version) { /* initialize version flags when version wraps around */ + if (! version) { /* initialize version flags when version wraps around */ version = INIT_ATTS_VERSION; - for (j = nsAttsSize; j != 0; ) + for (j = nsAttsSize; j != 0;) parser->m_nsAtts[--j].version = version; } parser->m_nsAttsVersion = --version; @@ -3389,7 +3252,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, /* expand prefixed names and check for duplicates */ for (; i < attIndex; i += 2) { const XML_Char *s = appAtts[i]; - if (s[-1] == 2) { /* prefixed */ + if (s[-1] == 2) { /* prefixed */ ATTRIBUTE_ID *id; const BINDING *b; unsigned long uriHash; @@ -3399,9 +3262,9 @@ storeAtts(XML_Parser parser, const ENCODING *enc, copy_salt_to_sipkey(parser, &sip_key); sip24_init(&sip_state, &sip_key); - ((XML_Char *)s)[-1] = 0; /* clear flag */ + ((XML_Char *)s)[-1] = 0; /* clear flag */ id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0); - if (!id || !id->prefix) { + if (! id || ! id->prefix) { /* This code is walking through the appAtts array, dealing * with (in this case) a prefixed attribute name. To be in * the array, the attribute must have already been bound, so @@ -3419,12 +3282,12 @@ storeAtts(XML_Parser parser, const ENCODING *enc, return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ } b = id->prefix->binding; - if (!b) + if (! b) return XML_ERROR_UNBOUND_PREFIX; for (j = 0; j < b->uriLen; j++) { const XML_Char c = b->uri[j]; - if (!poolAppendChar(&parser->m_tempPool, c)) + if (! poolAppendChar(&parser->m_tempPool, c)) return XML_ERROR_NO_MEMORY; } @@ -3435,8 +3298,8 @@ storeAtts(XML_Parser parser, const ENCODING *enc, sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char)); - do { /* copies null terminator */ - if (!poolAppendChar(&parser->m_tempPool, *s)) + do { /* copies null terminator */ + if (! poolAppendChar(&parser->m_tempPool, *s)) return XML_ERROR_NO_MEMORY; } while (*s++); @@ -3447,28 +3310,29 @@ storeAtts(XML_Parser parser, const ENCODING *enc, */ unsigned char step = 0; unsigned long mask = nsAttsSize - 1; - j = uriHash & mask; /* index into hash table */ + j = uriHash & mask; /* index into hash table */ while (parser->m_nsAtts[j].version == version) { /* for speed we compare stored hash values first */ if (uriHash == parser->m_nsAtts[j].hash) { const XML_Char *s1 = poolStart(&parser->m_tempPool); const XML_Char *s2 = parser->m_nsAtts[j].uriName; /* s1 is null terminated, but not s2 */ - for (; *s1 == *s2 && *s1 != 0; s1++, s2++); + for (; *s1 == *s2 && *s1 != 0; s1++, s2++) + ; if (*s1 == 0) return XML_ERROR_DUPLICATE_ATTRIBUTE; } - if (!step) + if (! step) step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower); j < step ? (j += nsAttsSize - step) : (j -= step); } } - if (parser->m_ns_triplets) { /* append namespace separator and prefix */ + if (parser->m_ns_triplets) { /* append namespace separator and prefix */ parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator; s = b->prefix->name; do { - if (!poolAppendChar(&parser->m_tempPool, *s)) + if (! poolAppendChar(&parser->m_tempPool, *s)) return XML_ERROR_NO_MEMORY; } while (*s++); } @@ -3483,13 +3347,12 @@ storeAtts(XML_Parser parser, const ENCODING *enc, parser->m_nsAtts[j].hash = uriHash; parser->m_nsAtts[j].uriName = s; - if (!--nPrefixes) { + if (! --nPrefixes) { i += 2; break; } - } - else /* not prefixed */ - ((XML_Char *)s)[-1] = 0; /* clear flag */ + } else /* not prefixed */ + ((XML_Char *)s)[-1] = 0; /* clear flag */ } } /* clear flags for the remaining attributes */ @@ -3498,40 +3361,38 @@ storeAtts(XML_Parser parser, const ENCODING *enc, for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) binding->attId->name[-1] = 0; - if (!parser->m_ns) + if (! parser->m_ns) return XML_ERROR_NONE; /* expand the element type name */ if (elementType->prefix) { binding = elementType->prefix->binding; - if (!binding) + if (! binding) return XML_ERROR_UNBOUND_PREFIX; localPart = tagNamePtr->str; while (*localPart++ != XML_T(ASCII_COLON)) ; - } - else if (dtd->defaultPrefix.binding) { + } else if (dtd->defaultPrefix.binding) { binding = dtd->defaultPrefix.binding; localPart = tagNamePtr->str; - } - else + } else return XML_ERROR_NONE; prefixLen = 0; if (parser->m_ns_triplets && binding->prefix->name) { for (; binding->prefix->name[prefixLen++];) - ; /* prefixLen includes null terminator */ + ; /* prefixLen includes null terminator */ } tagNamePtr->localPart = localPart; tagNamePtr->uriLen = binding->uriLen; tagNamePtr->prefix = binding->prefix->name; tagNamePtr->prefixLen = prefixLen; for (i = 0; localPart[i++];) - ; /* i includes null terminator */ + ; /* i includes null terminator */ n = i + binding->uriLen + prefixLen; if (n > binding->uriAlloc) { TAG *p; uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char)); - if (!uri) + if (! uri) return XML_ERROR_NO_MEMORY; binding->uriAlloc = n + EXPAND_SPARE; memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); @@ -3547,7 +3408,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, /* we always have a namespace separator between localPart and prefix */ if (prefixLen) { uri += i - 1; - *uri = parser->m_namespaceSeparator; /* replace null terminator */ + *uri = parser->m_namespaceSeparator; /* replace null terminator */ memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); } tagNamePtr->str = binding->uri; @@ -3559,27 +3420,25 @@ storeAtts(XML_Parser parser, const ENCODING *enc, */ static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, - const XML_Char *uri, BINDING **bindingsPtr) -{ - 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, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, - ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, - ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH, - ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, - ASCII_e, '\0' - }; - static const int xmlLen = - (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1; - 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, ASCII_3, ASCII_PERIOD, - ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0, - ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, - ASCII_SLASH, '\0' - }; - static const int xmlnsLen = - (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1; + const XML_Char *uri, BINDING **bindingsPtr) { + 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, + ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, + ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, + ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, + ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, + ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, + ASCII_e, '\0'}; + static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; + 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, + ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, + ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x, + ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'}; + static const int xmlnsLen + = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1; XML_Bool mustBeXML = XML_FALSE; XML_Bool isXML = XML_TRUE; @@ -3592,14 +3451,11 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, if (*uri == XML_T('\0') && prefix->name) return XML_ERROR_UNDECLARING_PREFIX; - if (prefix->name - && prefix->name[0] == XML_T(ASCII_x) + if (prefix->name && prefix->name[0] == XML_T(ASCII_x) && prefix->name[1] == XML_T(ASCII_m) && prefix->name[2] == XML_T(ASCII_l)) { - /* Not allowed to bind xmlns */ - if (prefix->name[3] == XML_T(ASCII_n) - && prefix->name[4] == XML_T(ASCII_s) + if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s) && prefix->name[5] == XML_T('\0')) return XML_ERROR_RESERVED_PREFIX_XMLNS; @@ -3611,7 +3467,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len])) isXML = XML_FALSE; - if (!mustBeXML && isXMLNS + if (! mustBeXML && isXMLNS && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) isXMLNS = XML_FALSE; } @@ -3630,21 +3486,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, if (parser->m_freeBindingList) { b = parser->m_freeBindingList; if (len > b->uriAlloc) { - XML_Char *temp = (XML_Char *)REALLOC(parser, b->uri, - sizeof(XML_Char) * (len + EXPAND_SPARE)); + XML_Char *temp = (XML_Char *)REALLOC( + parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE)); if (temp == NULL) return XML_ERROR_NO_MEMORY; b->uri = temp; b->uriAlloc = len + EXPAND_SPARE; } parser->m_freeBindingList = b->nextTagBinding; - } - else { + } else { b = (BINDING *)MALLOC(parser, sizeof(BINDING)); - if (!b) + if (! b) return XML_ERROR_NO_MEMORY; - b->uri = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); - if (!b->uri) { + b->uri + = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); + if (! b->uri) { FREE(parser, b); return XML_ERROR_NO_MEMORY; } @@ -3667,7 +3523,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, /* if attId == NULL then we are not starting a namespace scope */ if (attId && parser->m_startNamespaceDeclHandler) parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name, - prefix->binding ? uri : 0); + prefix->binding ? uri : 0); return XML_ERROR_NONE; } @@ -3675,21 +3531,18 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, the whole file is parsed with one call. */ static enum XML_Error PTRCALL -cdataSectionProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = doCdataSection(parser, parser->m_encoding, &start, end, - endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); +cdataSectionProcessor(XML_Parser parser, const char *start, const char *end, + const char **endPtr) { + enum XML_Error result + = doCdataSection(parser, parser->m_encoding, &start, end, endPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer); if (result != XML_ERROR_NONE) return result; if (start) { - if (parser->m_parentParser) { /* we are parsing an external entity */ + if (parser->m_parentParser) { /* we are parsing an external entity */ parser->m_processor = externalEntityContentProcessor; return externalEntityContentProcessor(parser, start, end, endPtr); - } - else { + } else { parser->m_processor = contentProcessor; return contentProcessor(parser, start, end, endPtr); } @@ -3701,13 +3554,8 @@ cdataSectionProcessor(XML_Parser parser, the section is not yet closed. */ static enum XML_Error -doCdataSection(XML_Parser parser, - const ENCODING *enc, - const char **startPtr, - const char *end, - const char **nextPtr, - XML_Bool haveMore) -{ +doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, + const char *end, const char **nextPtr, XML_Bool haveMore) { const char *s = *startPtr; const char **eventPP; const char **eventEndPP; @@ -3715,8 +3563,7 @@ doCdataSection(XML_Parser parser, eventPP = &parser->m_eventPtr; *eventPP = s; eventEndPP = &parser->m_eventEndPtr; - } - else { + } else { eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); } @@ -3731,11 +3578,12 @@ doCdataSection(XML_Parser parser, case XML_TOK_CDATA_SECT_CLOSE: if (parser->m_endCdataSectionHandler) parser->m_endCdataSectionHandler(parser->m_handlerArg); -#if 0 + /* BEGIN disabled code */ /* see comment under XML_TOK_CDATA_SECT_OPEN */ - else if (parser->m_characterDataHandler) - parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0); -#endif + else if (0 && parser->m_characterDataHandler) + parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, + 0); + /* END disabled code */ else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); *startPtr = next; @@ -3748,35 +3596,31 @@ doCdataSection(XML_Parser parser, if (parser->m_characterDataHandler) { XML_Char c = 0xA; parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); - } - else if (parser->m_defaultHandler) + } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; - case XML_TOK_DATA_CHARS: - { - XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; - if (charDataHandler) { - if (MUST_CONVERT(enc, s)) { - for (;;) { - ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; - const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); - *eventEndPP = next; - charDataHandler(parser->m_handlerArg, parser->m_dataBuf, - (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); - if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) - break; - *eventPP = s; - } + case XML_TOK_DATA_CHARS: { + XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; + if (charDataHandler) { + if (MUST_CONVERT(enc, s)) { + for (;;) { + ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; + const enum XML_Convert_Result convert_res = XmlConvert( + enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); + *eventEndPP = next; + charDataHandler(parser->m_handlerArg, parser->m_dataBuf, + (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); + if ((convert_res == XML_CONVERT_COMPLETED) + || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) + break; + *eventPP = s; } - else - charDataHandler(parser->m_handlerArg, - (XML_Char *)s, - (int)((XML_Char *)next - (XML_Char *)s)); - } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - } - break; + } else + charDataHandler(parser->m_handlerArg, (XML_Char *)s, + (int)((XML_Char *)next - (XML_Char *)s)); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + } break; case XML_TOK_INVALID: *eventPP = next; return XML_ERROR_INVALID_TOKEN; @@ -3800,7 +3644,7 @@ doCdataSection(XML_Parser parser, * statistics. * * LCOV_EXCL_START - */ + */ *eventPP = next; return XML_ERROR_UNEXPECTED_STATE; /* LCOV_EXCL_STOP */ @@ -3813,7 +3657,7 @@ doCdataSection(XML_Parser parser, return XML_ERROR_NONE; case XML_FINISHED: return XML_ERROR_ABORTED; - default: ; + default:; } } /* not reached */ @@ -3825,13 +3669,11 @@ doCdataSection(XML_Parser parser, the whole file is parsed with one call. */ static enum XML_Error PTRCALL -ignoreSectionProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = doIgnoreSection(parser, parser->m_encoding, &start, end, - endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); +ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end, + const char **endPtr) { + enum XML_Error result + = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer); if (result != XML_ERROR_NONE) return result; if (start) { @@ -3845,13 +3687,8 @@ ignoreSectionProcessor(XML_Parser parser, if the section is not yet closed. */ static enum XML_Error -doIgnoreSection(XML_Parser parser, - const ENCODING *enc, - const char **startPtr, - const char *end, - const char **nextPtr, - XML_Bool haveMore) -{ +doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, + const char *end, const char **nextPtr, XML_Bool haveMore) { const char *next; int tok; const char *s = *startPtr; @@ -3861,8 +3698,7 @@ doIgnoreSection(XML_Parser parser, eventPP = &parser->m_eventPtr; *eventPP = s; eventEndPP = &parser->m_eventEndPtr; - } - else { + } else { /* It's not entirely clear, but it seems the following two lines * of code cannot be executed. The only occasions on which 'enc' * is not 'encoding' are when this function is called @@ -3926,13 +3762,12 @@ doIgnoreSection(XML_Parser parser, #endif /* XML_DTD */ static enum XML_Error -initializeEncoding(XML_Parser parser) -{ +initializeEncoding(XML_Parser parser) { const char *s; #ifdef XML_UNICODE char encodingBuf[128]; /* See comments abount `protoclEncodingName` in parserInit() */ - if (!parser->m_protocolEncodingName) + if (! parser->m_protocolEncodingName) s = NULL; else { int i; @@ -3950,15 +3785,15 @@ initializeEncoding(XML_Parser parser) #else s = parser->m_protocolEncodingName; #endif - if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(&parser->m_initEncoding, &parser->m_encoding, s)) + if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)( + &parser->m_initEncoding, &parser->m_encoding, s)) return XML_ERROR_NONE; return handleUnknownEncoding(parser, parser->m_protocolEncodingName); } static enum XML_Error -processXmlDecl(XML_Parser parser, int isGeneralTextEntity, - const char *s, const char *next) -{ +processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s, + const char *next) { const char *encodingName = NULL; const XML_Char *storedEncName = NULL; const ENCODING *newEncoding = NULL; @@ -3966,52 +3801,41 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *versionend; const XML_Char *storedversion = NULL; int standalone = -1; - if (!(parser->m_ns - ? XmlParseXmlDeclNS - : XmlParseXmlDecl)(isGeneralTextEntity, - parser->m_encoding, - s, - next, - &parser->m_eventPtr, - &version, - &versionend, - &encodingName, - &newEncoding, - &standalone)) { + if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)( + isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr, + &version, &versionend, &encodingName, &newEncoding, &standalone)) { if (isGeneralTextEntity) return XML_ERROR_TEXT_DECL; else return XML_ERROR_XML_DECL; } - if (!isGeneralTextEntity && standalone == 1) { + if (! isGeneralTextEntity && standalone == 1) { parser->m_dtd->standalone = XML_TRUE; #ifdef XML_DTD - if (parser->m_paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) + if (parser->m_paramEntityParsing + == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; #endif /* XML_DTD */ } if (parser->m_xmlDeclHandler) { if (encodingName != NULL) { - storedEncName = poolStoreString(&parser->m_temp2Pool, - parser->m_encoding, - encodingName, - encodingName - + XmlNameLength(parser->m_encoding, encodingName)); - if (!storedEncName) - return XML_ERROR_NO_MEMORY; + storedEncName = poolStoreString( + &parser->m_temp2Pool, parser->m_encoding, encodingName, + encodingName + XmlNameLength(parser->m_encoding, encodingName)); + if (! storedEncName) + return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_temp2Pool); } if (version) { - storedversion = poolStoreString(&parser->m_temp2Pool, - parser->m_encoding, - version, - versionend - parser->m_encoding->minBytesPerChar); - if (!storedversion) + storedversion + = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version, + versionend - parser->m_encoding->minBytesPerChar); + if (! storedversion) return XML_ERROR_NO_MEMORY; } - parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, standalone); - } - else if (parser->m_defaultHandler) + parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, + standalone); + } else if (parser->m_defaultHandler) reportDefault(parser, parser->m_encoding, s, next); if (parser->m_protocolEncodingName == NULL) { if (newEncoding) { @@ -4021,20 +3845,19 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, * this is UTF-16, is it the same endianness? */ if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar - || (newEncoding->minBytesPerChar == 2 && - newEncoding != parser->m_encoding)) { + || (newEncoding->minBytesPerChar == 2 + && newEncoding != parser->m_encoding)) { parser->m_eventPtr = encodingName; return XML_ERROR_INCORRECT_ENCODING; } parser->m_encoding = newEncoding; - } - else if (encodingName) { + } else if (encodingName) { enum XML_Error result; - if (!storedEncName) { + if (! storedEncName) { storedEncName = poolStoreString( - &parser->m_temp2Pool, parser->m_encoding, encodingName, - encodingName + XmlNameLength(parser->m_encoding, encodingName)); - if (!storedEncName) + &parser->m_temp2Pool, parser->m_encoding, encodingName, + encodingName + XmlNameLength(parser->m_encoding, encodingName)); + if (! storedEncName) return XML_ERROR_NO_MEMORY; } result = handleUnknownEncoding(parser, storedEncName); @@ -4052,8 +3875,7 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, } static enum XML_Error -handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) -{ +handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) { if (parser->m_unknownEncodingHandler) { XML_Encoding info; int i; @@ -4062,21 +3884,17 @@ handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) info.convert = NULL; info.data = NULL; info.release = NULL; - if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, encodingName, - &info)) { + if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, + encodingName, &info)) { ENCODING *enc; parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding()); - if (!parser->m_unknownEncodingMem) { + if (! parser->m_unknownEncodingMem) { if (info.release) info.release(info.data); return XML_ERROR_NO_MEMORY; } - enc = (parser->m_ns - ? XmlInitUnknownEncodingNS - : XmlInitUnknownEncoding)(parser->m_unknownEncodingMem, - info.map, - info.convert, - info.data); + enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)( + parser->m_unknownEncodingMem, info.map, info.convert, info.data); if (enc) { parser->m_unknownEncodingData = info.data; parser->m_unknownEncodingRelease = info.release; @@ -4091,11 +3909,8 @@ handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) } static enum XML_Error PTRCALL -prologInitProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ +prologInitProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; @@ -4106,11 +3921,8 @@ prologInitProcessor(XML_Parser parser, #ifdef XML_DTD static enum XML_Error PTRCALL -externalParEntInitProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ +externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; @@ -4122,19 +3934,15 @@ externalParEntInitProcessor(XML_Parser parser, if (parser->m_prologState.inEntityValue) { parser->m_processor = entityValueInitProcessor; return entityValueInitProcessor(parser, s, end, nextPtr); - } - else { + } else { parser->m_processor = externalParEntProcessor; return externalParEntProcessor(parser, s, end, nextPtr); } } static enum XML_Error PTRCALL -entityValueInitProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ +entityValueInitProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { int tok; const char *start = s; const char *next = start; @@ -4144,7 +3952,7 @@ entityValueInitProcessor(XML_Parser parser, tok = XmlPrologTok(parser->m_encoding, start, end, &next); parser->m_eventEndPtr = next; if (tok <= 0) { - if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { + if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } @@ -4155,22 +3963,21 @@ entityValueInitProcessor(XML_Parser parser, return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_NONE: /* start == end */ + case XML_TOK_NONE: /* start == end */ default: break; } /* found end of entity value - can store it now */ return storeEntityValue(parser, parser->m_encoding, s, end); - } - else if (tok == XML_TOK_XML_DECL) { + } else if (tok == XML_TOK_XML_DECL) { enum XML_Error result; result = processXmlDecl(parser, 0, start, next); if (result != XML_ERROR_NONE) return result; - /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For that - * to happen, a parameter entity parsing handler must have - * attempted to suspend the parser, which fails and raises an - * error. The parser can be aborted, but can't be suspended. + /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For + * that to happen, a parameter entity parsing handler must have attempted + * to suspend the parser, which fails and raises an error. The parser can + * be aborted, but can't be suspended. */ if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; @@ -4186,7 +3993,8 @@ entityValueInitProcessor(XML_Parser parser, then, when this routine is entered the next time, XmlPrologTok will return XML_TOK_INVALID, since the BOM is still in the buffer */ - else if (tok == XML_TOK_BOM && next == end && !parser->m_parsingStatus.finalBuffer) { + else if (tok == XML_TOK_BOM && next == end + && ! parser->m_parsingStatus.finalBuffer) { *nextPtr = next; return XML_ERROR_NONE; } @@ -4204,17 +4012,14 @@ entityValueInitProcessor(XML_Parser parser, } static enum XML_Error PTRCALL -externalParEntProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ +externalParEntProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { const char *next = s; int tok; tok = XmlPrologTok(parser->m_encoding, s, end, &next); if (tok <= 0) { - if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { + if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } @@ -4225,7 +4030,7 @@ externalParEntProcessor(XML_Parser parser, return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_NONE: /* start == end */ + case XML_TOK_NONE: /* start == end */ default: break; } @@ -4240,16 +4045,13 @@ externalParEntProcessor(XML_Parser parser, } parser->m_processor = prologProcessor; - return doProlog(parser, parser->m_encoding, s, end, tok, next, - nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); + return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE); } static enum XML_Error PTRCALL -entityValueProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ +entityValueProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { const char *start = s; const char *next = s; const ENCODING *enc = parser->m_encoding; @@ -4258,7 +4060,7 @@ entityValueProcessor(XML_Parser parser, for (;;) { tok = XmlPrologTok(enc, start, end, &next); if (tok <= 0) { - if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { + if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } @@ -4269,7 +4071,7 @@ entityValueProcessor(XML_Parser parser, return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_NONE: /* start == end */ + case XML_TOK_NONE: /* start == end */ default: break; } @@ -4283,52 +4085,46 @@ entityValueProcessor(XML_Parser parser, #endif /* XML_DTD */ static enum XML_Error PTRCALL -prologProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ +prologProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { const char *next = s; int tok = XmlPrologTok(parser->m_encoding, s, end, &next); - return doProlog(parser, parser->m_encoding, s, end, tok, next, - nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); + return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE); } static enum XML_Error -doProlog(XML_Parser parser, - const ENCODING *enc, - const char *s, - const char *end, - int tok, - const char *next, - const char **nextPtr, - XML_Bool haveMore) -{ +doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, + int tok, const char *next, const char **nextPtr, XML_Bool haveMore, + XML_Bool allowClosingDoctype) { #ifdef XML_DTD - static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' }; + static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'}; #endif /* XML_DTD */ - static const XML_Char atypeCDATA[] = - { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; - static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' }; - static const XML_Char atypeIDREF[] = - { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; - static const XML_Char atypeIDREFS[] = - { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; - static const XML_Char atypeENTITY[] = - { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; - static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N, - ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' }; - static const XML_Char atypeNMTOKEN[] = { - ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; - static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, - ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' }; - static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T, - ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' }; - static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' }; - static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' }; + static const XML_Char atypeCDATA[] + = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; + static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'}; + static const XML_Char atypeIDREF[] + = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'}; + static const XML_Char atypeIDREFS[] + = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'}; + static const XML_Char atypeENTITY[] + = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'}; + static const XML_Char atypeENTITIES[] + = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, + ASCII_I, ASCII_E, ASCII_S, '\0'}; + static const XML_Char atypeNMTOKEN[] + = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'}; + static const XML_Char atypeNMTOKENS[] + = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, + ASCII_E, ASCII_N, ASCII_S, '\0'}; + static const XML_Char notationPrefix[] + = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, + ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'}; + static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'}; + static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'}; /* save one level of indirection */ - DTD * const dtd = parser->m_dtd; + DTD *const dtd = parser->m_dtd; const char **eventPP; const char **eventEndPP; @@ -4337,8 +4133,7 @@ doProlog(XML_Parser parser, if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; eventEndPP = &parser->m_eventEndPtr; - } - else { + } else { eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); } @@ -4367,7 +4162,8 @@ doProlog(XML_Parser parser, case XML_TOK_NONE: #ifdef XML_DTD /* for internal PE NOT referenced between declarations */ - if (enc != parser->m_encoding && !parser->m_openInternalEntities->betweenDecl) { + if (enc != parser->m_encoding + && ! parser->m_openInternalEntities->betweenDecl) { *nextPtr = s; return XML_ERROR_NONE; } @@ -4392,19 +4188,18 @@ doProlog(XML_Parser parser, } role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc); switch (role) { - case XML_ROLE_XML_DECL: - { - enum XML_Error result = processXmlDecl(parser, 0, s, next); - if (result != XML_ERROR_NONE) - return result; - enc = parser->m_encoding; - handleDefault = XML_FALSE; - } - break; + case XML_ROLE_XML_DECL: { + enum XML_Error result = processXmlDecl(parser, 0, s, next); + if (result != XML_ERROR_NONE) + return result; + enc = parser->m_encoding; + handleDefault = XML_FALSE; + } break; case XML_ROLE_DOCTYPE_NAME: if (parser->m_startDoctypeDeclHandler) { - parser->m_doctypeName = poolStoreString(&parser->m_tempPool, enc, s, next); - if (!parser->m_doctypeName) + parser->m_doctypeName + = poolStoreString(&parser->m_tempPool, enc, s, next); + if (! parser->m_doctypeName) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); parser->m_doctypePubid = NULL; @@ -4414,43 +4209,40 @@ doProlog(XML_Parser parser, break; case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: if (parser->m_startDoctypeDeclHandler) { - parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, - parser->m_doctypePubid, 1); + parser->m_startDoctypeDeclHandler( + parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, + parser->m_doctypePubid, 1); parser->m_doctypeName = NULL; poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } break; #ifdef XML_DTD - case XML_ROLE_TEXT_DECL: - { - enum XML_Error result = processXmlDecl(parser, 1, s, next); - if (result != XML_ERROR_NONE) - return result; - enc = parser->m_encoding; - handleDefault = XML_FALSE; - } - break; + case XML_ROLE_TEXT_DECL: { + enum XML_Error result = processXmlDecl(parser, 1, s, next); + if (result != XML_ERROR_NONE) + return result; + enc = parser->m_encoding; + handleDefault = XML_FALSE; + } break; #endif /* XML_DTD */ case XML_ROLE_DOCTYPE_PUBLIC_ID: #ifdef XML_DTD parser->m_useForeignDTD = XML_FALSE; - parser->m_declEntity = (ENTITY *)lookup(parser, - &dtd->paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!parser->m_declEntity) + parser->m_declEntity = (ENTITY *)lookup( + parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); + if (! parser->m_declEntity) return XML_ERROR_NO_MEMORY; #endif /* XML_DTD */ dtd->hasParamEntityRefs = XML_TRUE; if (parser->m_startDoctypeDeclHandler) { XML_Char *pubId; - if (!XmlIsPublicId(enc, s, next, eventPP)) + if (! XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_PUBLICID; pubId = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); - if (!pubId) + if (! pubId) return XML_ERROR_NO_MEMORY; normalizePublicId(pubId); poolFinish(&parser->m_tempPool); @@ -4460,15 +4252,14 @@ doProlog(XML_Parser parser, } /* fall through */ case XML_ROLE_ENTITY_PUBLIC_ID: - if (!XmlIsPublicId(enc, s, next, eventPP)) + if (! XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_PUBLICID; alreadyChecked: if (dtd->keepProcessing && parser->m_declEntity) { - XML_Char *tem = poolStoreString(&dtd->pool, - enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!tem) + XML_Char *tem + = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); parser->m_declEntity->publicId = tem; @@ -4481,9 +4272,15 @@ doProlog(XML_Parser parser, } break; case XML_ROLE_DOCTYPE_CLOSE: + if (allowClosingDoctype != XML_TRUE) { + /* Must not close doctype from within expanded parameter entities */ + return XML_ERROR_INVALID_TOKEN; + } + if (parser->m_doctypeName) { - parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName, - parser->m_doctypeSysid, parser->m_doctypePubid, 0); + parser->m_startDoctypeDeclHandler( + parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, + parser->m_doctypePubid, 0); poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } @@ -4495,12 +4292,11 @@ doProlog(XML_Parser parser, if (parser->m_doctypeSysid || parser->m_useForeignDTD) { XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; dtd->hasParamEntityRefs = XML_TRUE; - if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) { - ENTITY *entity = (ENTITY *)lookup(parser, - &dtd->paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!entity) { + if (parser->m_paramEntityParsing + && parser->m_externalEntityRefHandler) { + ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, + externalSubsetName, sizeof(ENTITY)); + if (! entity) { /* The external subset name "#" will have already been * inserted into the hash table at the start of the * external entity parsing, so no allocation will happen @@ -4511,22 +4307,19 @@ doProlog(XML_Parser parser, if (parser->m_useForeignDTD) entity->base = parser->m_curBase; dtd->paramEntityRead = XML_FALSE; - if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) + if (! parser->m_externalEntityRefHandler( + parser->m_externalEntityRefHandlerArg, 0, entity->base, + entity->systemId, entity->publicId)) return XML_ERROR_EXTERNAL_ENTITY_HANDLING; if (dtd->paramEntityRead) { - if (!dtd->standalone && - parser->m_notStandaloneHandler && - !parser->m_notStandaloneHandler(parser->m_handlerArg)) + if (! dtd->standalone && parser->m_notStandaloneHandler + && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; } /* if we didn't read the foreign DTD then this means that there is no external subset and we must reset dtd->hasParamEntityRefs */ - else if (!parser->m_doctypeSysid) + else if (! parser->m_doctypeSysid) dtd->hasParamEntityRefs = hadParamEntityRefs; /* end of DTD - no need to update dtd->keepProcessing */ } @@ -4546,24 +4339,21 @@ doProlog(XML_Parser parser, if (parser->m_useForeignDTD) { XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; dtd->hasParamEntityRefs = XML_TRUE; - if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) { + if (parser->m_paramEntityParsing + && parser->m_externalEntityRefHandler) { ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!entity) + externalSubsetName, sizeof(ENTITY)); + if (! entity) return XML_ERROR_NO_MEMORY; entity->base = parser->m_curBase; dtd->paramEntityRead = XML_FALSE; - if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) + if (! parser->m_externalEntityRefHandler( + parser->m_externalEntityRefHandlerArg, 0, entity->base, + entity->systemId, entity->publicId)) return XML_ERROR_EXTERNAL_ENTITY_HANDLING; if (dtd->paramEntityRead) { - if (!dtd->standalone && - parser->m_notStandaloneHandler && - !parser->m_notStandaloneHandler(parser->m_handlerArg)) + if (! dtd->standalone && parser->m_notStandaloneHandler + && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; } /* if we didn't read the foreign DTD then this means that there @@ -4579,12 +4369,12 @@ doProlog(XML_Parser parser, return contentProcessor(parser, s, end, nextPtr); case XML_ROLE_ATTLIST_ELEMENT_NAME: parser->m_declElementType = getElementType(parser, enc, s, next); - if (!parser->m_declElementType) + if (! parser->m_declElementType) return XML_ERROR_NO_MEMORY; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_NAME: parser->m_declAttributeId = getAttributeId(parser, enc, s, next); - if (!parser->m_declAttributeId) + if (! parser->m_declAttributeId) return XML_ERROR_NO_MEMORY; parser->m_declAttributeIsCdata = XML_FALSE; parser->m_declAttributeType = NULL; @@ -4625,15 +4415,13 @@ doProlog(XML_Parser parser, const XML_Char *prefix; if (parser->m_declAttributeType) { prefix = enumValueSep; + } else { + prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix + : enumValueStart); } - else { - prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE - ? notationPrefix - : enumValueStart); - } - if (!poolAppendString(&parser->m_tempPool, prefix)) + if (! poolAppendString(&parser->m_tempPool, prefix)) return XML_ERROR_NO_MEMORY; - if (!poolAppend(&parser->m_tempPool, enc, s, next)) + if (! poolAppend(&parser->m_tempPool, enc, s, next)) return XML_ERROR_NO_MEMORY; parser->m_declAttributeType = parser->m_tempPool.start; handleDefault = XML_FALSE; @@ -4642,25 +4430,27 @@ doProlog(XML_Parser parser, case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: if (dtd->keepProcessing) { - if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId, - parser->m_declAttributeIsCdata, parser->m_declAttributeIsId, - 0, parser)) + if (! defineAttribute(parser->m_declElementType, + parser->m_declAttributeId, + parser->m_declAttributeIsCdata, + parser->m_declAttributeIsId, 0, parser)) return XML_ERROR_NO_MEMORY; if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) || (*parser->m_declAttributeType == XML_T(ASCII_N) && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { /* Enumerated or Notation type */ - if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) - || !poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) + || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_ERROR_NO_MEMORY; parser->m_declAttributeType = parser->m_tempPool.start; poolFinish(&parser->m_tempPool); } *eventEndPP = s; - parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, - parser->m_declAttributeId->name, parser->m_declAttributeType, - 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); + parser->m_attlistDeclHandler( + 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; } @@ -4670,35 +4460,34 @@ doProlog(XML_Parser parser, case XML_ROLE_FIXED_ATTRIBUTE_VALUE: if (dtd->keepProcessing) { const XML_Char *attVal; - enum XML_Error result = - storeAttributeValue(parser, enc, parser->m_declAttributeIsCdata, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar, - &dtd->pool); + enum XML_Error result = storeAttributeValue( + parser, enc, parser->m_declAttributeIsCdata, + s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool); if (result) return result; attVal = poolStart(&dtd->pool); poolFinish(&dtd->pool); /* ID attributes aren't allowed to have a default */ - if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId, - parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser)) + if (! defineAttribute( + parser->m_declElementType, parser->m_declAttributeId, + parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser)) return XML_ERROR_NO_MEMORY; if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) || (*parser->m_declAttributeType == XML_T(ASCII_N) && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { /* Enumerated or Notation type */ - if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) - || !poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) + || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_ERROR_NO_MEMORY; parser->m_declAttributeType = parser->m_tempPool.start; poolFinish(&parser->m_tempPool); } *eventEndPP = s; - parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, - parser->m_declAttributeId->name, parser->m_declAttributeType, - attVal, - role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); + parser->m_attlistDeclHandler( + parser->m_handlerArg, parser->m_declElementType->name, + parser->m_declAttributeId->name, parser->m_declAttributeType, + attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } @@ -4706,25 +4495,22 @@ doProlog(XML_Parser parser, break; case XML_ROLE_ENTITY_VALUE: if (dtd->keepProcessing) { - enum XML_Error result = storeEntityValue(parser, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); + enum XML_Error result = storeEntityValue( + parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (parser->m_declEntity) { parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool); - parser->m_declEntity->textLen = (int)(poolLength(&dtd->entityValuePool)); + parser->m_declEntity->textLen + = (int)(poolLength(&dtd->entityValuePool)); poolFinish(&dtd->entityValuePool); if (parser->m_entityDeclHandler) { *eventEndPP = s; - parser->m_entityDeclHandler(parser->m_handlerArg, - parser->m_declEntity->name, - parser->m_declEntity->is_param, - parser->m_declEntity->textPtr, - parser->m_declEntity->textLen, - parser->m_curBase, 0, 0, 0); + parser->m_entityDeclHandler( + parser->m_handlerArg, parser->m_declEntity->name, + parser->m_declEntity->is_param, parser->m_declEntity->textPtr, + parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0); handleDefault = XML_FALSE; } - } - else + } else poolDiscard(&dtd->entityValuePool); if (result != XML_ERROR_NONE) return result; @@ -4737,8 +4523,8 @@ doProlog(XML_Parser parser, dtd->hasParamEntityRefs = XML_TRUE; if (parser->m_startDoctypeDeclHandler) { parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); if (parser->m_doctypeSysid == NULL) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); @@ -4750,22 +4536,20 @@ doProlog(XML_Parser parser, for the case where no parser->m_startDoctypeDeclHandler is set */ parser->m_doctypeSysid = externalSubsetName; #endif /* XML_DTD */ - if (!dtd->standalone + if (! dtd->standalone #ifdef XML_DTD - && !parser->m_paramEntityParsing + && ! parser->m_paramEntityParsing #endif /* XML_DTD */ && parser->m_notStandaloneHandler - && !parser->m_notStandaloneHandler(parser->m_handlerArg)) + && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; #ifndef XML_DTD break; -#else /* XML_DTD */ - if (!parser->m_declEntity) { - parser->m_declEntity = (ENTITY *)lookup(parser, - &dtd->paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!parser->m_declEntity) +#else /* XML_DTD */ + if (! parser->m_declEntity) { + parser->m_declEntity = (ENTITY *)lookup( + parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); + if (! parser->m_declEntity) return XML_ERROR_NO_MEMORY; parser->m_declEntity->publicId = NULL; } @@ -4773,10 +4557,10 @@ doProlog(XML_Parser parser, /* fall through */ case XML_ROLE_ENTITY_SYSTEM_ID: if (dtd->keepProcessing && parser->m_declEntity) { - parser->m_declEntity->systemId = poolStoreString(&dtd->pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!parser->m_declEntity->systemId) + parser->m_declEntity->systemId + = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! parser->m_declEntity->systemId) return XML_ERROR_NO_MEMORY; parser->m_declEntity->base = parser->m_curBase; poolFinish(&dtd->pool); @@ -4788,115 +4572,103 @@ doProlog(XML_Parser parser, } break; case XML_ROLE_ENTITY_COMPLETE: - if (dtd->keepProcessing && parser->m_declEntity && parser->m_entityDeclHandler) { + if (dtd->keepProcessing && parser->m_declEntity + && parser->m_entityDeclHandler) { *eventEndPP = s; - parser->m_entityDeclHandler(parser->m_handlerArg, - parser->m_declEntity->name, - parser->m_declEntity->is_param, - 0,0, - parser->m_declEntity->base, - parser->m_declEntity->systemId, - parser->m_declEntity->publicId, - 0); + parser->m_entityDeclHandler( + parser->m_handlerArg, parser->m_declEntity->name, + parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base, + parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0); handleDefault = XML_FALSE; } break; case XML_ROLE_ENTITY_NOTATION_NAME: if (dtd->keepProcessing && parser->m_declEntity) { - parser->m_declEntity->notation = poolStoreString(&dtd->pool, enc, s, next); - if (!parser->m_declEntity->notation) + parser->m_declEntity->notation + = poolStoreString(&dtd->pool, enc, s, next); + if (! parser->m_declEntity->notation) return XML_ERROR_NO_MEMORY; poolFinish(&dtd->pool); if (parser->m_unparsedEntityDeclHandler) { *eventEndPP = s; - parser->m_unparsedEntityDeclHandler(parser->m_handlerArg, - parser->m_declEntity->name, - parser->m_declEntity->base, - parser->m_declEntity->systemId, - parser->m_declEntity->publicId, - parser->m_declEntity->notation); + parser->m_unparsedEntityDeclHandler( + parser->m_handlerArg, parser->m_declEntity->name, + parser->m_declEntity->base, parser->m_declEntity->systemId, + parser->m_declEntity->publicId, parser->m_declEntity->notation); handleDefault = XML_FALSE; - } - else if (parser->m_entityDeclHandler) { + } else if (parser->m_entityDeclHandler) { *eventEndPP = s; - parser->m_entityDeclHandler(parser->m_handlerArg, - parser->m_declEntity->name, - 0,0,0, - parser->m_declEntity->base, - parser->m_declEntity->systemId, - parser->m_declEntity->publicId, - parser->m_declEntity->notation); + parser->m_entityDeclHandler( + parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0, + parser->m_declEntity->base, parser->m_declEntity->systemId, + parser->m_declEntity->publicId, parser->m_declEntity->notation); handleDefault = XML_FALSE; } } break; - case XML_ROLE_GENERAL_ENTITY_NAME: - { - if (XmlPredefinedEntityName(enc, s, next)) { - parser->m_declEntity = NULL; - break; - } - if (dtd->keepProcessing) { - const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); - if (!name) - return XML_ERROR_NO_MEMORY; - parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, - sizeof(ENTITY)); - if (!parser->m_declEntity) - return XML_ERROR_NO_MEMORY; - if (parser->m_declEntity->name != name) { - poolDiscard(&dtd->pool); - parser->m_declEntity = NULL; - } - else { - poolFinish(&dtd->pool); - parser->m_declEntity->publicId = NULL; - parser->m_declEntity->is_param = XML_FALSE; - /* if we have a parent parser or are reading an internal parameter - entity, then the entity declaration is not considered "internal" - */ - parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities); - if (parser->m_entityDeclHandler) - handleDefault = XML_FALSE; - } - } - else { + case XML_ROLE_GENERAL_ENTITY_NAME: { + if (XmlPredefinedEntityName(enc, s, next)) { + parser->m_declEntity = NULL; + break; + } + if (dtd->keepProcessing) { + const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); + if (! name) + return XML_ERROR_NO_MEMORY; + parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, + name, sizeof(ENTITY)); + if (! parser->m_declEntity) + return XML_ERROR_NO_MEMORY; + if (parser->m_declEntity->name != name) { poolDiscard(&dtd->pool); parser->m_declEntity = NULL; + } else { + poolFinish(&dtd->pool); + parser->m_declEntity->publicId = NULL; + parser->m_declEntity->is_param = XML_FALSE; + /* if we have a parent parser or are reading an internal parameter + entity, then the entity declaration is not considered "internal" + */ + parser->m_declEntity->is_internal + = ! (parser->m_parentParser || parser->m_openInternalEntities); + if (parser->m_entityDeclHandler) + handleDefault = XML_FALSE; } + } else { + poolDiscard(&dtd->pool); + parser->m_declEntity = NULL; } - break; + } break; case XML_ROLE_PARAM_ENTITY_NAME: #ifdef XML_DTD if (dtd->keepProcessing) { const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); - if (!name) + if (! name) return XML_ERROR_NO_MEMORY; parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, - name, sizeof(ENTITY)); - if (!parser->m_declEntity) + name, sizeof(ENTITY)); + if (! parser->m_declEntity) return XML_ERROR_NO_MEMORY; if (parser->m_declEntity->name != name) { poolDiscard(&dtd->pool); parser->m_declEntity = NULL; - } - else { + } else { poolFinish(&dtd->pool); parser->m_declEntity->publicId = NULL; parser->m_declEntity->is_param = XML_TRUE; /* if we have a parent parser or are reading an internal parameter entity, then the entity declaration is not considered "internal" */ - parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities); + parser->m_declEntity->is_internal + = ! (parser->m_parentParser || parser->m_openInternalEntities); if (parser->m_entityDeclHandler) handleDefault = XML_FALSE; } - } - else { + } else { poolDiscard(&dtd->pool); parser->m_declEntity = NULL; } -#else /* not XML_DTD */ +#else /* not XML_DTD */ parser->m_declEntity = NULL; #endif /* XML_DTD */ break; @@ -4904,22 +4676,23 @@ doProlog(XML_Parser parser, parser->m_declNotationPublicId = NULL; parser->m_declNotationName = NULL; if (parser->m_notationDeclHandler) { - parser->m_declNotationName = poolStoreString(&parser->m_tempPool, enc, s, next); - if (!parser->m_declNotationName) + parser->m_declNotationName + = poolStoreString(&parser->m_tempPool, enc, s, next); + if (! parser->m_declNotationName) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); handleDefault = XML_FALSE; } break; case XML_ROLE_NOTATION_PUBLIC_ID: - if (!XmlIsPublicId(enc, s, next, eventPP)) + if (! XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_PUBLICID; - if (parser->m_declNotationName) { /* means m_notationDeclHandler != NULL */ - XML_Char *tem = poolStoreString(&parser->m_tempPool, - enc, + if (parser + ->m_declNotationName) { /* means m_notationDeclHandler != NULL */ + XML_Char *tem = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); - if (!tem) + if (! tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); parser->m_declNotationPublicId = tem; @@ -4929,18 +4702,15 @@ doProlog(XML_Parser parser, break; case XML_ROLE_NOTATION_SYSTEM_ID: if (parser->m_declNotationName && parser->m_notationDeclHandler) { - const XML_Char *systemId - = poolStoreString(&parser->m_tempPool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!systemId) + const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! systemId) return XML_ERROR_NO_MEMORY; *eventEndPP = s; - parser->m_notationDeclHandler(parser->m_handlerArg, - parser->m_declNotationName, - parser->m_curBase, - systemId, - parser->m_declNotationPublicId); + parser->m_notationDeclHandler( + parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, + systemId, parser->m_declNotationPublicId); handleDefault = XML_FALSE; } poolClear(&parser->m_tempPool); @@ -4948,11 +4718,9 @@ doProlog(XML_Parser parser, case XML_ROLE_NOTATION_NO_SYSTEM_ID: if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) { *eventEndPP = s; - parser->m_notationDeclHandler(parser->m_handlerArg, - parser->m_declNotationName, - parser->m_curBase, - 0, - parser->m_declNotationPublicId); + parser->m_notationDeclHandler( + parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, + 0, parser->m_declNotationPublicId); handleDefault = XML_FALSE; } poolClear(&parser->m_tempPool); @@ -4969,42 +4737,44 @@ doProlog(XML_Parser parser, return XML_ERROR_SYNTAX; } #ifdef XML_DTD - case XML_ROLE_IGNORE_SECT: - { - enum XML_Error result; - if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - handleDefault = XML_FALSE; - result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); - if (result != XML_ERROR_NONE) - return result; - else if (!next) { - parser->m_processor = ignoreSectionProcessor; - return result; - } + case XML_ROLE_IGNORE_SECT: { + enum XML_Error result; + if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + handleDefault = XML_FALSE; + result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); + if (result != XML_ERROR_NONE) + return result; + else if (! next) { + parser->m_processor = ignoreSectionProcessor; + return result; } - break; + } break; #endif /* XML_DTD */ case XML_ROLE_GROUP_OPEN: if (parser->m_prologState.level >= parser->m_groupSize) { if (parser->m_groupSize) { - char *temp = (char *)REALLOC(parser, parser->m_groupConnector, parser->m_groupSize *= 2); - if (temp == NULL) { - parser->m_groupSize /= 2; - return XML_ERROR_NO_MEMORY; + { + char *const new_connector = (char *)REALLOC( + parser, parser->m_groupConnector, parser->m_groupSize *= 2); + if (new_connector == NULL) { + parser->m_groupSize /= 2; + return XML_ERROR_NO_MEMORY; + } + parser->m_groupConnector = new_connector; } - parser->m_groupConnector = temp; + if (dtd->scaffIndex) { - int *temp = (int *)REALLOC(parser, dtd->scaffIndex, - parser->m_groupSize * sizeof(int)); - if (temp == NULL) + int *const new_scaff_index = (int *)REALLOC( + parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int)); + if (new_scaff_index == NULL) return XML_ERROR_NO_MEMORY; - dtd->scaffIndex = temp; + dtd->scaffIndex = new_scaff_index; } - } - else { - parser->m_groupConnector = (char *)MALLOC(parser, parser->m_groupSize = 32); - if (!parser->m_groupConnector) { + } else { + parser->m_groupConnector + = (char *)MALLOC(parser, parser->m_groupSize = 32); + if (! parser->m_groupConnector) { parser->m_groupSize = 0; return XML_ERROR_NO_MEMORY; } @@ -5015,6 +4785,7 @@ doProlog(XML_Parser parser, int myindex = nextScaffoldPart(parser); if (myindex < 0) return XML_ERROR_NO_MEMORY; + assert(dtd->scaffIndex != NULL); dtd->scaffIndex[dtd->scaffLevel] = myindex; dtd->scaffLevel++; dtd->scaffold[myindex].type = XML_CTYPE_SEQ; @@ -5033,10 +4804,9 @@ doProlog(XML_Parser parser, if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA) return XML_ERROR_SYNTAX; if (dtd->in_eldecl - && !parser->m_groupConnector[parser->m_prologState.level] + && ! parser->m_groupConnector[parser->m_prologState.level] && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type - != XML_CTYPE_MIXED) - ) { + != XML_CTYPE_MIXED)) { dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type = XML_CTYPE_CHOICE; if (parser->m_elementDeclHandler) @@ -5048,15 +4818,14 @@ doProlog(XML_Parser parser, #ifdef XML_DTD case XML_ROLE_INNER_PARAM_ENTITY_REF: dtd->hasParamEntityRefs = XML_TRUE; - if (!parser->m_paramEntityParsing) + if (! parser->m_paramEntityParsing) dtd->keepProcessing = dtd->standalone; else { const XML_Char *name; ENTITY *entity; - name = poolStoreString(&dtd->pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) + name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! name) return XML_ERROR_NO_MEMORY; entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); poolDiscard(&dtd->pool); @@ -5064,13 +4833,12 @@ doProlog(XML_Parser parser, if yes, check that the entity exists, and that it is internal, otherwise call the skipped entity handler */ - if (parser->m_prologState.documentEntity && - (dtd->standalone - ? !parser->m_openInternalEntities - : !dtd->hasParamEntityRefs)) { - if (!entity) + if (parser->m_prologState.documentEntity + && (dtd->standalone ? ! parser->m_openInternalEntities + : ! dtd->hasParamEntityRefs)) { + if (! entity) return XML_ERROR_UNDEFINED_ENTITY; - else if (!entity->is_internal) { + else if (! entity->is_internal) { /* It's hard to exhaustively search the code to be sure, * but there doesn't seem to be a way of executing the * following line. There are two cases: @@ -5093,11 +4861,11 @@ doProlog(XML_Parser parser, */ return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */ } - } - else if (!entity) { + } else if (! entity) { dtd->keepProcessing = dtd->standalone; /* cannot report skipped entities in declarations */ - if ((role == XML_ROLE_PARAM_ENTITY_REF) && parser->m_skippedEntityHandler) { + if ((role == XML_ROLE_PARAM_ENTITY_REF) + && parser->m_skippedEntityHandler) { parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1); handleDefault = XML_FALSE; } @@ -5107,8 +4875,8 @@ doProlog(XML_Parser parser, return XML_ERROR_RECURSIVE_ENTITY_REF; if (entity->textPtr) { enum XML_Error result; - XML_Bool betweenDecl = - (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); + XML_Bool betweenDecl + = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); result = processInternalEntity(parser, entity, betweenDecl); if (result != XML_ERROR_NONE) return result; @@ -5118,39 +4886,35 @@ doProlog(XML_Parser parser, if (parser->m_externalEntityRefHandler) { dtd->paramEntityRead = XML_FALSE; entity->open = XML_TRUE; - if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) { + if (! parser->m_externalEntityRefHandler( + parser->m_externalEntityRefHandlerArg, 0, entity->base, + entity->systemId, entity->publicId)) { entity->open = XML_FALSE; return XML_ERROR_EXTERNAL_ENTITY_HANDLING; } entity->open = XML_FALSE; handleDefault = XML_FALSE; - if (!dtd->paramEntityRead) { + if (! dtd->paramEntityRead) { dtd->keepProcessing = dtd->standalone; break; } - } - else { + } else { dtd->keepProcessing = dtd->standalone; break; } } #endif /* XML_DTD */ - if (!dtd->standalone && - parser->m_notStandaloneHandler && - !parser->m_notStandaloneHandler(parser->m_handlerArg)) + if (! dtd->standalone && parser->m_notStandaloneHandler + && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; break; - /* Element declaration stuff */ + /* Element declaration stuff */ case XML_ROLE_ELEMENT_NAME: if (parser->m_elementDeclHandler) { parser->m_declElementType = getElementType(parser, enc, s, next); - if (!parser->m_declElementType) + if (! parser->m_declElementType) return XML_ERROR_NO_MEMORY; dtd->scaffLevel = 0; dtd->scaffCount = 0; @@ -5163,18 +4927,19 @@ doProlog(XML_Parser parser, case XML_ROLE_CONTENT_EMPTY: if (dtd->in_eldecl) { if (parser->m_elementDeclHandler) { - XML_Content * content = (XML_Content *) MALLOC(parser, sizeof(XML_Content)); - if (!content) + XML_Content *content + = (XML_Content *)MALLOC(parser, sizeof(XML_Content)); + if (! content) return XML_ERROR_NO_MEMORY; content->quant = XML_CQUANT_NONE; content->name = NULL; content->numchildren = 0; content->children = NULL; - content->type = ((role == XML_ROLE_CONTENT_ANY) ? - XML_CTYPE_ANY : - XML_CTYPE_EMPTY); + content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY + : XML_CTYPE_EMPTY); *eventEndPP = s; - parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, content); + parser->m_elementDeclHandler( + parser->m_handlerArg, parser->m_declElementType->name, content); handleDefault = XML_FALSE; } dtd->in_eldecl = XML_FALSE; @@ -5206,22 +4971,22 @@ doProlog(XML_Parser parser, ELEMENT_TYPE *el; const XML_Char *name; int nameLen; - const char *nxt = (quant == XML_CQUANT_NONE - ? next - : next - enc->minBytesPerChar); + const char *nxt + = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar); int myindex = nextScaffoldPart(parser); if (myindex < 0) return XML_ERROR_NO_MEMORY; dtd->scaffold[myindex].type = XML_CTYPE_NAME; dtd->scaffold[myindex].quant = quant; el = getElementType(parser, enc, s, nxt); - if (!el) + if (! el) return XML_ERROR_NO_MEMORY; name = el->name; dtd->scaffold[myindex].name = name; nameLen = 0; - for (; name[nameLen++]; ); - dtd->contentStringLen += nameLen; + for (; name[nameLen++];) + ; + dtd->contentStringLen += nameLen; if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } @@ -5245,12 +5010,13 @@ doProlog(XML_Parser parser, dtd->scaffLevel--; dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; if (dtd->scaffLevel == 0) { - if (!handleDefault) { + if (! handleDefault) { XML_Content *model = build_model(parser); - if (!model) + if (! model) return XML_ERROR_NO_MEMORY; *eventEndPP = s; - parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, model); + parser->m_elementDeclHandler( + parser->m_handlerArg, parser->m_declElementType->name, model); } dtd->in_eldecl = XML_FALSE; dtd->contentStringLen = 0; @@ -5260,12 +5026,12 @@ doProlog(XML_Parser parser, /* End element declaration stuff */ case XML_ROLE_PI: - if (!reportProcessingInstruction(parser, enc, s, next)) + if (! reportProcessingInstruction(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; handleDefault = XML_FALSE; break; case XML_ROLE_COMMENT: - if (!reportComment(parser, enc, s, next)) + if (! reportComment(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; handleDefault = XML_FALSE; break; @@ -5316,11 +5082,8 @@ doProlog(XML_Parser parser, } static enum XML_Error PTRCALL -epilogProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ +epilogProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { parser->m_processor = epilogProcessor; parser->m_eventPtr = s; for (;;) { @@ -5345,24 +5108,24 @@ epilogProcessor(XML_Parser parser, reportDefault(parser, parser->m_encoding, s, next); break; case XML_TOK_PI: - if (!reportProcessingInstruction(parser, parser->m_encoding, s, next)) + if (! reportProcessingInstruction(parser, parser->m_encoding, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_COMMENT: - if (!reportComment(parser, parser->m_encoding, s, next)) + if (! reportComment(parser, parser->m_encoding, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_INVALID: parser->m_eventPtr = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: - if (!parser->m_parsingStatus.finalBuffer) { + if (! parser->m_parsingStatus.finalBuffer) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: - if (!parser->m_parsingStatus.finalBuffer) { + if (! parser->m_parsingStatus.finalBuffer) { *nextPtr = s; return XML_ERROR_NONE; } @@ -5377,15 +5140,13 @@ epilogProcessor(XML_Parser parser, return XML_ERROR_NONE; case XML_FINISHED: return XML_ERROR_ABORTED; - default: ; + default:; } } } static enum XML_Error -processInternalEntity(XML_Parser parser, ENTITY *entity, - XML_Bool betweenDecl) -{ +processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) { const char *textStart, *textEnd; const char *next; enum XML_Error result; @@ -5394,10 +5155,10 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, if (parser->m_freeInternalEntities) { openEntity = parser->m_freeInternalEntities; parser->m_freeInternalEntities = openEntity->next; - } - else { - openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY)); - if (!openEntity) + } else { + openEntity + = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY)); + if (! openEntity) return XML_ERROR_NO_MEMORY; } entity->open = XML_TRUE; @@ -5416,21 +5177,20 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, #ifdef XML_DTD if (entity->is_param) { - int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); - result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok, - next, &next, XML_FALSE); - } - else + int tok + = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); + result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, + tok, next, &next, XML_FALSE, XML_FALSE); + } else #endif /* XML_DTD */ - result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, textStart, - textEnd, &next, XML_FALSE); + result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, + textStart, textEnd, &next, XML_FALSE); if (result == XML_ERROR_NONE) { if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { entity->processed = (int)(next - textStart); parser->m_processor = internalEntityProcessor; - } - else { + } else { entity->open = XML_FALSE; parser->m_openInternalEntities = openEntity->next; /* put openEntity back in list of free instances */ @@ -5442,17 +5202,14 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, } static enum XML_Error PTRCALL -internalEntityProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ +internalEntityProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { ENTITY *entity; const char *textStart, *textEnd; const char *next; enum XML_Error result; OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities; - if (!openEntity) + if (! openEntity) return XML_ERROR_UNEXPECTED_STATE; entity = openEntity->entity; @@ -5463,22 +5220,23 @@ internalEntityProcessor(XML_Parser parser, #ifdef XML_DTD if (entity->is_param) { - int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); - result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok, - next, &next, XML_FALSE); - } - else + int tok + = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); + result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, + tok, next, &next, XML_FALSE, XML_TRUE); + } else #endif /* XML_DTD */ - result = doContent(parser, openEntity->startTagLevel, parser->m_internalEncoding, - textStart, textEnd, &next, XML_FALSE); + result = doContent(parser, openEntity->startTagLevel, + parser->m_internalEncoding, textStart, textEnd, &next, + XML_FALSE); if (result != XML_ERROR_NONE) return result; - else if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { + else if (textEnd != next + && parser->m_parsingStatus.parsing == XML_SUSPENDED) { entity->processed = (int)(next - (char *)entity->textPtr); return result; - } - else { + } else { entity->open = XML_FALSE; parser->m_openInternalEntities = openEntity->next; /* put openEntity back in list of free instances */ @@ -5492,49 +5250,45 @@ internalEntityProcessor(XML_Parser parser, parser->m_processor = prologProcessor; tok = XmlPrologTok(parser->m_encoding, s, end, &next); return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, - (XML_Bool)!parser->m_parsingStatus.finalBuffer); - } - else + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE); + } else #endif /* XML_DTD */ { 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); + return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, + s, end, nextPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer); } } static enum XML_Error PTRCALL -errorProcessor(XML_Parser parser, - const char *UNUSED_P(s), - const char *UNUSED_P(end), - const char **UNUSED_P(nextPtr)) -{ +errorProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { + UNUSED_P(s); + UNUSED_P(end); + UNUSED_P(nextPtr); return parser->m_errorCode; } static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, - const char *ptr, const char *end, - STRING_POOL *pool) -{ - enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, - end, pool); + const char *ptr, const char *end, STRING_POOL *pool) { + enum XML_Error result + = appendAttributeValue(parser, enc, isCdata, ptr, end, pool); if (result) return result; - if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) + if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) poolChop(pool); - if (!poolAppendChar(pool, XML_T('\0'))) + if (! poolAppendChar(pool, XML_T('\0'))) return XML_ERROR_NO_MEMORY; return XML_ERROR_NONE; } static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, - const char *ptr, const char *end, - STRING_POOL *pool) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ + const char *ptr, const char *end, STRING_POOL *pool) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ for (;;) { const char *next; int tok = XmlAttributeValueTok(enc, ptr, end, &next); @@ -5549,38 +5303,35 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, if (enc == parser->m_encoding) parser->m_eventPtr = ptr; return XML_ERROR_INVALID_TOKEN; - case XML_TOK_CHAR_REF: - { - XML_Char buf[XML_ENCODE_MAX]; - int i; - int n = XmlCharRefNumber(enc, ptr); - if (n < 0) { - if (enc == parser->m_encoding) - parser->m_eventPtr = ptr; - return XML_ERROR_BAD_CHAR_REF; - } - if (!isCdata - && n == 0x20 /* space */ - && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) - break; - n = XmlEncode(n, (ICHAR *)buf); - /* The XmlEncode() functions can never return 0 here. That - * error return happens if the code point passed in is either - * negative or greater than or equal to 0x110000. The - * XmlCharRefNumber() functions will all return a number - * strictly less than 0x110000 or a negative value if an error - * occurred. The negative value is intercepted above, so - * XmlEncode() is never passed a value it might return an - * error for. - */ - for (i = 0; i < n; i++) { - if (!poolAppendChar(pool, buf[i])) - return XML_ERROR_NO_MEMORY; - } + case XML_TOK_CHAR_REF: { + XML_Char buf[XML_ENCODE_MAX]; + int i; + int n = XmlCharRefNumber(enc, ptr); + if (n < 0) { + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; + return XML_ERROR_BAD_CHAR_REF; } - break; + if (! isCdata && n == 0x20 /* space */ + && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) + break; + n = XmlEncode(n, (ICHAR *)buf); + /* The XmlEncode() functions can never return 0 here. That + * error return happens if the code point passed in is either + * negative or greater than or equal to 0x110000. The + * XmlCharRefNumber() functions will all return a number + * strictly less than 0x110000 or a negative value if an error + * occurred. The negative value is intercepted above, so + * XmlEncode() is never passed a value it might return an + * error for. + */ + for (i = 0; i < n; i++) { + if (! poolAppendChar(pool, buf[i])) + return XML_ERROR_NO_MEMORY; + } + } break; case XML_TOK_DATA_CHARS: - if (!poolAppend(pool, enc, ptr, next)) + if (! poolAppend(pool, enc, ptr, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_TRAILING_CR: @@ -5588,109 +5339,103 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, /* fall through */ case XML_TOK_ATTRIBUTE_VALUE_S: case XML_TOK_DATA_NEWLINE: - if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) + if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) break; - if (!poolAppendChar(pool, 0x20)) + if (! poolAppendChar(pool, 0x20)) return XML_ERROR_NO_MEMORY; break; - case XML_TOK_ENTITY_REF: - { - const XML_Char *name; - ENTITY *entity; - char checkEntityDecl; - XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, - ptr + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (ch) { - if (!poolAppendChar(pool, ch)) - return XML_ERROR_NO_MEMORY; - break; - } - name = poolStoreString(&parser->m_temp2Pool, enc, - ptr + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) + case XML_TOK_ENTITY_REF: { + const XML_Char *name; + ENTITY *entity; + char checkEntityDecl; + XML_Char ch = (XML_Char)XmlPredefinedEntityName( + enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); + if (ch) { + if (! poolAppendChar(pool, ch)) return XML_ERROR_NO_MEMORY; - entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); - poolDiscard(&parser->m_temp2Pool); - /* First, determine if a check for an existing declaration is needed; - if yes, check that the entity exists, and that it is internal. - */ - if (pool == &dtd->pool) /* are we called from prolog? */ - checkEntityDecl = + break; + } + name = poolStoreString(&parser->m_temp2Pool, enc, + ptr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); + poolDiscard(&parser->m_temp2Pool); + /* First, determine if a check for an existing declaration is needed; + if yes, check that the entity exists, and that it is internal. + */ + if (pool == &dtd->pool) /* are we called from prolog? */ + checkEntityDecl = #ifdef XML_DTD - parser->m_prologState.documentEntity && + parser->m_prologState.documentEntity && #endif /* XML_DTD */ - (dtd->standalone - ? !parser->m_openInternalEntities - : !dtd->hasParamEntityRefs); - else /* if (pool == &parser->m_tempPool): we are called from content */ - checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone; - if (checkEntityDecl) { - if (!entity) - return XML_ERROR_UNDEFINED_ENTITY; - else if (!entity->is_internal) - return XML_ERROR_ENTITY_DECLARED_IN_PE; - } - else if (!entity) { - /* Cannot report skipped entity here - see comments on - parser->m_skippedEntityHandler. - if (parser->m_skippedEntityHandler) - parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); - */ - /* Cannot call the default handler because this would be - out of sync with the call to the startElementHandler. - if ((pool == &parser->m_tempPool) && parser->m_defaultHandler) - reportDefault(parser, enc, ptr, next); - */ - break; - } - if (entity->open) { - if (enc == parser->m_encoding) { - /* It does not appear that this line can be executed. - * - * The "if (entity->open)" check catches recursive entity - * definitions. In order to be called with an open - * entity, it must have gone through this code before and - * been through the recursive call to - * appendAttributeValue() some lines below. That call - * sets the local encoding ("enc") to the parser's - * internal encoding (internal_utf8 or internal_utf16), - * which can never be the same as the principle encoding. - * It doesn't appear there is another code path that gets - * here with entity->open being TRUE. - * - * Since it is not certain that this logic is watertight, - * we keep the line and merely exclude it from coverage - * tests. - */ - parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */ - } - return XML_ERROR_RECURSIVE_ENTITY_REF; - } - if (entity->notation) { - if (enc == parser->m_encoding) - parser->m_eventPtr = ptr; - return XML_ERROR_BINARY_ENTITY_REF; - } - if (!entity->textPtr) { - if (enc == parser->m_encoding) - parser->m_eventPtr = ptr; - return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; - } - else { - enum XML_Error result; - const XML_Char *textEnd = entity->textPtr + entity->textLen; - entity->open = XML_TRUE; - result = appendAttributeValue(parser, parser->m_internalEncoding, isCdata, - (char *)entity->textPtr, - (char *)textEnd, pool); - entity->open = XML_FALSE; - if (result) - return result; + (dtd->standalone ? ! parser->m_openInternalEntities + : ! dtd->hasParamEntityRefs); + else /* if (pool == &parser->m_tempPool): we are called from content */ + checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone; + if (checkEntityDecl) { + if (! entity) + return XML_ERROR_UNDEFINED_ENTITY; + else if (! entity->is_internal) + return XML_ERROR_ENTITY_DECLARED_IN_PE; + } else if (! entity) { + /* Cannot report skipped entity here - see comments on + parser->m_skippedEntityHandler. + if (parser->m_skippedEntityHandler) + parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); + */ + /* Cannot call the default handler because this would be + out of sync with the call to the startElementHandler. + if ((pool == &parser->m_tempPool) && parser->m_defaultHandler) + reportDefault(parser, enc, ptr, next); + */ + break; + } + if (entity->open) { + if (enc == parser->m_encoding) { + /* It does not appear that this line can be executed. + * + * The "if (entity->open)" check catches recursive entity + * definitions. In order to be called with an open + * entity, it must have gone through this code before and + * been through the recursive call to + * appendAttributeValue() some lines below. That call + * sets the local encoding ("enc") to the parser's + * internal encoding (internal_utf8 or internal_utf16), + * which can never be the same as the principle encoding. + * It doesn't appear there is another code path that gets + * here with entity->open being TRUE. + * + * Since it is not certain that this logic is watertight, + * we keep the line and merely exclude it from coverage + * tests. + */ + parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */ } + return XML_ERROR_RECURSIVE_ENTITY_REF; } - break; + if (entity->notation) { + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; + return XML_ERROR_BINARY_ENTITY_REF; + } + if (! entity->textPtr) { + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; + return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; + } else { + enum XML_Error result; + const XML_Char *textEnd = entity->textPtr + entity->textLen; + entity->open = XML_TRUE; + result = appendAttributeValue(parser, parser->m_internalEncoding, + isCdata, (char *)entity->textPtr, + (char *)textEnd, pool); + entity->open = XML_FALSE; + if (result) + return result; + } + } break; default: /* The only token returned by XmlAttributeValueTok() that does * not have an explicit case here is XML_TOK_PARTIAL_CHAR. @@ -5714,12 +5459,9 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, } static enum XML_Error -storeEntityValue(XML_Parser parser, - const ENCODING *enc, - const char *entityTextPtr, - const char *entityTextEnd) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ +storeEntityValue(XML_Parser parser, const ENCODING *enc, + const char *entityTextPtr, const char *entityTextEnd) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ STRING_POOL *pool = &(dtd->entityValuePool); enum XML_Error result = XML_ERROR_NONE; #ifdef XML_DTD @@ -5729,8 +5471,8 @@ storeEntityValue(XML_Parser parser, /* never return Null for the value argument in EntityDeclHandler, since this would indicate an external entity; therefore we have to make sure that entityValuePool.start is not null */ - if (!pool->blocks) { - if (!poolGrow(pool)) + if (! pool->blocks) { + if (! poolGrow(pool)) return XML_ERROR_NO_MEMORY; } @@ -5746,13 +5488,13 @@ storeEntityValue(XML_Parser parser, name = poolStoreString(&parser->m_tempPool, enc, entityTextPtr + enc->minBytesPerChar, next - enc->minBytesPerChar); - if (!name) { + if (! name) { result = XML_ERROR_NO_MEMORY; goto endEntityValue; } entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); poolDiscard(&parser->m_tempPool); - if (!entity) { + if (! entity) { /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ /* cannot report skipped entity here - see comments on parser->m_skippedEntityHandler @@ -5772,29 +5514,23 @@ storeEntityValue(XML_Parser parser, if (parser->m_externalEntityRefHandler) { dtd->paramEntityRead = XML_FALSE; entity->open = XML_TRUE; - if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) { + if (! parser->m_externalEntityRefHandler( + parser->m_externalEntityRefHandlerArg, 0, entity->base, + entity->systemId, entity->publicId)) { entity->open = XML_FALSE; result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; goto endEntityValue; } entity->open = XML_FALSE; - if (!dtd->paramEntityRead) + if (! dtd->paramEntityRead) dtd->keepProcessing = dtd->standalone; - } - else + } else dtd->keepProcessing = dtd->standalone; - } - else { + } else { entity->open = XML_TRUE; - result = storeEntityValue(parser, - parser->m_internalEncoding, - (char *)entity->textPtr, - (char *)(entity->textPtr - + entity->textLen)); + result = storeEntityValue( + parser, parser->m_internalEncoding, (char *)entity->textPtr, + (char *)(entity->textPtr + entity->textLen)); entity->open = XML_FALSE; if (result) goto endEntityValue; @@ -5812,7 +5548,7 @@ storeEntityValue(XML_Parser parser, goto endEntityValue; case XML_TOK_ENTITY_REF: case XML_TOK_DATA_CHARS: - if (!poolAppend(pool, enc, entityTextPtr, next)) { + if (! poolAppend(pool, enc, entityTextPtr, next)) { result = XML_ERROR_NO_MEMORY; goto endEntityValue; } @@ -5821,42 +5557,40 @@ storeEntityValue(XML_Parser parser, next = entityTextPtr + enc->minBytesPerChar; /* fall through */ case XML_TOK_DATA_NEWLINE: - if (pool->end == pool->ptr && !poolGrow(pool)) { - result = XML_ERROR_NO_MEMORY; + if (pool->end == pool->ptr && ! poolGrow(pool)) { + result = XML_ERROR_NO_MEMORY; goto endEntityValue; } *(pool->ptr)++ = 0xA; break; - case XML_TOK_CHAR_REF: - { - XML_Char buf[XML_ENCODE_MAX]; - int i; - int n = XmlCharRefNumber(enc, entityTextPtr); - if (n < 0) { - if (enc == parser->m_encoding) - parser->m_eventPtr = entityTextPtr; - result = XML_ERROR_BAD_CHAR_REF; + case XML_TOK_CHAR_REF: { + XML_Char buf[XML_ENCODE_MAX]; + int i; + int n = XmlCharRefNumber(enc, entityTextPtr); + if (n < 0) { + if (enc == parser->m_encoding) + parser->m_eventPtr = entityTextPtr; + result = XML_ERROR_BAD_CHAR_REF; + goto endEntityValue; + } + n = XmlEncode(n, (ICHAR *)buf); + /* The XmlEncode() functions can never return 0 here. That + * error return happens if the code point passed in is either + * negative or greater than or equal to 0x110000. The + * XmlCharRefNumber() functions will all return a number + * strictly less than 0x110000 or a negative value if an error + * occurred. The negative value is intercepted above, so + * XmlEncode() is never passed a value it might return an + * error for. + */ + for (i = 0; i < n; i++) { + if (pool->end == pool->ptr && ! poolGrow(pool)) { + result = XML_ERROR_NO_MEMORY; goto endEntityValue; } - n = XmlEncode(n, (ICHAR *)buf); - /* The XmlEncode() functions can never return 0 here. That - * error return happens if the code point passed in is either - * negative or greater than or equal to 0x110000. The - * XmlCharRefNumber() functions will all return a number - * strictly less than 0x110000 or a negative value if an error - * occurred. The negative value is intercepted above, so - * XmlEncode() is never passed a value it might return an - * error for. - */ - for (i = 0; i < n; i++) { - if (pool->end == pool->ptr && !poolGrow(pool)) { - result = XML_ERROR_NO_MEMORY; - goto endEntityValue; - } - *(pool->ptr)++ = buf[i]; - } + *(pool->ptr)++ = buf[i]; } - break; + } break; case XML_TOK_PARTIAL: if (enc == parser->m_encoding) parser->m_eventPtr = entityTextPtr; @@ -5891,8 +5625,7 @@ storeEntityValue(XML_Parser parser, } static void FASTCALL -normalizeLines(XML_Char *s) -{ +normalizeLines(XML_Char *s) { XML_Char *p; for (;; s++) { if (*s == XML_T('\0')) @@ -5906,8 +5639,7 @@ normalizeLines(XML_Char *s) *p++ = 0xA; if (*++s == 0xA) s++; - } - else + } else *p++ = *s++; } while (*s); *p = XML_T('\0'); @@ -5915,12 +5647,11 @@ normalizeLines(XML_Char *s) static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, - const char *start, const char *end) -{ + const char *start, const char *end) { const XML_Char *target; XML_Char *data; const char *tem; - if (!parser->m_processingInstructionHandler) { + if (! parser->m_processingInstructionHandler) { if (parser->m_defaultHandler) reportDefault(parser, enc, start, end); return 1; @@ -5928,13 +5659,12 @@ reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, start += enc->minBytesPerChar * 2; tem = start + XmlNameLength(enc, start); target = poolStoreString(&parser->m_tempPool, enc, start, tem); - if (!target) + if (! target) return 0; poolFinish(&parser->m_tempPool); - data = poolStoreString(&parser->m_tempPool, enc, - XmlSkipS(enc, tem), - end - enc->minBytesPerChar*2); - if (!data) + data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem), + end - enc->minBytesPerChar * 2); + if (! data) return 0; normalizeLines(data); parser->m_processingInstructionHandler(parser->m_handlerArg, target, data); @@ -5943,20 +5673,18 @@ reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, } static int -reportComment(XML_Parser parser, const ENCODING *enc, - const char *start, const char *end) -{ +reportComment(XML_Parser parser, const ENCODING *enc, const char *start, + const char *end) { XML_Char *data; - if (!parser->m_commentHandler) { + if (! parser->m_commentHandler) { if (parser->m_defaultHandler) reportDefault(parser, enc, start, end); return 1; } - data = poolStoreString(&parser->m_tempPool, - enc, + data = poolStoreString(&parser->m_tempPool, enc, start + enc->minBytesPerChar * 4, end - enc->minBytesPerChar * 3); - if (!data) + if (! data) return 0; normalizeLines(data); parser->m_commentHandler(parser->m_handlerArg, data); @@ -5965,9 +5693,8 @@ reportComment(XML_Parser parser, const ENCODING *enc, } static void -reportDefault(XML_Parser parser, const ENCODING *enc, - const char *s, const char *end) -{ +reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, + const char *end) { if (MUST_CONVERT(enc, s)) { enum XML_Convert_Result convert_res; const char **eventPP; @@ -5975,8 +5702,7 @@ reportDefault(XML_Parser parser, const ENCODING *enc, if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; eventEndPP = &parser->m_eventEndPtr; - } - else { + } else { /* To get here, two things must be true; the parser must be * using a character encoding that is not the same as the * encoding passed in, and the encoding passed in must need @@ -5999,21 +5725,22 @@ reportDefault(XML_Parser parser, const ENCODING *enc, } do { ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; - convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); + convert_res + = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); *eventEndPP = s; - parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); + parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, + (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); *eventPP = s; - } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE)); - } - else - parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s)); + } while ((convert_res != XML_CONVERT_COMPLETED) + && (convert_res != XML_CONVERT_INPUT_INCOMPLETE)); + } else + parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s, + (int)((XML_Char *)end - (XML_Char *)s)); } - static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, - XML_Bool isId, const XML_Char *value, XML_Parser parser) -{ + XML_Bool isId, const XML_Char *value, XML_Parser parser) { DEFAULT_ATTRIBUTE *att; if (value || isId) { /* The handling of default attributes gets messed up if we have @@ -6022,24 +5749,23 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, for (i = 0; i < type->nDefaultAtts; i++) if (attId == type->defaultAtts[i].id) return 1; - if (isId && !type->idAtt && !attId->xmlns) + if (isId && ! type->idAtt && ! attId->xmlns) type->idAtt = attId; } if (type->nDefaultAtts == type->allocDefaultAtts) { if (type->allocDefaultAtts == 0) { type->allocDefaultAtts = 8; - type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(parser, type->allocDefaultAtts - * sizeof(DEFAULT_ATTRIBUTE)); - if (!type->defaultAtts) { + type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC( + parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); + if (! type->defaultAtts) { type->allocDefaultAtts = 0; return 0; } - } - else { + } else { DEFAULT_ATTRIBUTE *temp; int count = type->allocDefaultAtts * 2; - temp = (DEFAULT_ATTRIBUTE *) - REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); + temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts, + (count * sizeof(DEFAULT_ATTRIBUTE))); if (temp == NULL) return 0; type->allocDefaultAtts = count; @@ -6050,92 +5776,89 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, att->id = attId; att->value = value; att->isCdata = isCdata; - if (!isCdata) + if (! isCdata) attId->maybeTokenized = XML_TRUE; type->nDefaultAtts += 1; return 1; } static int -setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ +setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ const XML_Char *name; for (name = elementType->name; *name; name++) { if (*name == XML_T(ASCII_COLON)) { PREFIX *prefix; const XML_Char *s; for (s = elementType->name; s != name; s++) { - if (!poolAppendChar(&dtd->pool, *s)) + if (! poolAppendChar(&dtd->pool, *s)) return 0; } - if (!poolAppendChar(&dtd->pool, XML_T('\0'))) + if (! poolAppendChar(&dtd->pool, XML_T('\0'))) return 0; prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), sizeof(PREFIX)); - if (!prefix) + if (! prefix) return 0; if (prefix->name == poolStart(&dtd->pool)) poolFinish(&dtd->pool); else poolDiscard(&dtd->pool); elementType->prefix = prefix; - + break; } } return 1; } static ATTRIBUTE_ID * -getAttributeId(XML_Parser parser, const ENCODING *enc, - const char *start, const char *end) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ +getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, + const char *end) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ ATTRIBUTE_ID *id; const XML_Char *name; - if (!poolAppendChar(&dtd->pool, XML_T('\0'))) + if (! poolAppendChar(&dtd->pool, XML_T('\0'))) return NULL; name = poolStoreString(&dtd->pool, enc, start, end); - if (!name) + if (! name) return NULL; /* skip quotation mark - its storage will be re-used (like in name[-1]) */ ++name; - id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID)); - if (!id) + id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, + sizeof(ATTRIBUTE_ID)); + if (! id) return NULL; if (id->name != name) poolDiscard(&dtd->pool); else { poolFinish(&dtd->pool); - if (!parser->m_ns) + if (! parser->m_ns) ; - else if (name[0] == XML_T(ASCII_x) - && name[1] == XML_T(ASCII_m) - && name[2] == XML_T(ASCII_l) - && name[3] == XML_T(ASCII_n) - && name[4] == XML_T(ASCII_s) - && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) { + else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m) + && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n) + && name[4] == XML_T(ASCII_s) + && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) { if (name[5] == XML_T('\0')) id->prefix = &dtd->defaultPrefix; else - id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX)); + id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, + sizeof(PREFIX)); id->xmlns = XML_TRUE; - } - else { + } else { int i; for (i = 0; name[i]; i++) { /* attributes without prefix are *not* in the default namespace */ if (name[i] == XML_T(ASCII_COLON)) { int j; for (j = 0; j < i; j++) { - if (!poolAppendChar(&dtd->pool, name[j])) + if (! poolAppendChar(&dtd->pool, name[j])) return NULL; } - if (!poolAppendChar(&dtd->pool, XML_T('\0'))) + if (! poolAppendChar(&dtd->pool, XML_T('\0'))) return NULL; - id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), - sizeof(PREFIX)); - if (!id->prefix) + id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, + poolStart(&dtd->pool), sizeof(PREFIX)); + if (! id->prefix) return NULL; if (id->prefix->name == poolStart(&dtd->pool)) poolFinish(&dtd->pool); @@ -6152,22 +5875,22 @@ getAttributeId(XML_Parser parser, const ENCODING *enc, #define CONTEXT_SEP XML_T(ASCII_FF) static const XML_Char * -getContext(XML_Parser parser) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ +getContext(XML_Parser parser) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ HASH_TABLE_ITER iter; XML_Bool needSep = XML_FALSE; if (dtd->defaultPrefix.binding) { int i; int len; - if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) + if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) return NULL; len = dtd->defaultPrefix.binding->uriLen; if (parser->m_namespaceSeparator) len--; for (i = 0; i < len; i++) { - if (!poolAppendChar(&parser->m_tempPool, dtd->defaultPrefix.binding->uri[i])) { + if (! poolAppendChar(&parser->m_tempPool, + dtd->defaultPrefix.binding->uri[i])) { /* Because of memory caching, I don't believe this line can be * executed. * @@ -6199,9 +5922,9 @@ getContext(XML_Parser parser) int len; const XML_Char *s; PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); - if (!prefix) + if (! prefix) break; - if (!prefix->binding) { + if (! prefix->binding) { /* This test appears to be (justifiable) paranoia. There does * not seem to be a way of injecting a prefix without a binding * that doesn't get errored long before this function is called. @@ -6210,98 +5933,96 @@ getContext(XML_Parser parser) */ continue; /* LCOV_EXCL_LINE */ } - if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) + if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) return NULL; for (s = prefix->name; *s; s++) - if (!poolAppendChar(&parser->m_tempPool, *s)) + if (! poolAppendChar(&parser->m_tempPool, *s)) return NULL; - if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) + if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) return NULL; len = prefix->binding->uriLen; if (parser->m_namespaceSeparator) len--; for (i = 0; i < len; i++) - if (!poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i])) + if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i])) return NULL; needSep = XML_TRUE; } - hashTableIterInit(&iter, &(dtd->generalEntities)); for (;;) { const XML_Char *s; ENTITY *e = (ENTITY *)hashTableIterNext(&iter); - if (!e) + if (! e) break; - if (!e->open) + if (! e->open) continue; - if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) + if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) return NULL; for (s = e->name; *s; s++) - if (!poolAppendChar(&parser->m_tempPool, *s)) + if (! poolAppendChar(&parser->m_tempPool, *s)) return 0; needSep = XML_TRUE; } - if (!poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return NULL; return parser->m_tempPool.start; } static XML_Bool -setContext(XML_Parser parser, const XML_Char *context) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ +setContext(XML_Parser parser, const XML_Char *context) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ const XML_Char *s = context; while (*context != XML_T('\0')) { if (*s == CONTEXT_SEP || *s == XML_T('\0')) { ENTITY *e; - if (!poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_FALSE; - e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&parser->m_tempPool), 0); + e = (ENTITY *)lookup(parser, &dtd->generalEntities, + poolStart(&parser->m_tempPool), 0); if (e) e->open = XML_TRUE; if (*s != XML_T('\0')) s++; context = s; poolDiscard(&parser->m_tempPool); - } - else if (*s == XML_T(ASCII_EQUALS)) { + } else if (*s == XML_T(ASCII_EQUALS)) { PREFIX *prefix; if (poolLength(&parser->m_tempPool) == 0) prefix = &dtd->defaultPrefix; else { - if (!poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_FALSE; - prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&parser->m_tempPool), - sizeof(PREFIX)); - if (!prefix) + prefix + = (PREFIX *)lookup(parser, &dtd->prefixes, + poolStart(&parser->m_tempPool), sizeof(PREFIX)); + if (! prefix) return XML_FALSE; if (prefix->name == poolStart(&parser->m_tempPool)) { prefix->name = poolCopyString(&dtd->pool, prefix->name); - if (!prefix->name) + if (! prefix->name) return XML_FALSE; } poolDiscard(&parser->m_tempPool); } - for (context = s + 1; - *context != CONTEXT_SEP && *context != XML_T('\0'); + for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++) - if (!poolAppendChar(&parser->m_tempPool, *context)) + if (! poolAppendChar(&parser->m_tempPool, *context)) return XML_FALSE; - if (!poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_FALSE; if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool), - &parser->m_inheritedBindings) != XML_ERROR_NONE) + &parser->m_inheritedBindings) + != XML_ERROR_NONE) return XML_FALSE; poolDiscard(&parser->m_tempPool); if (*context != XML_T('\0')) ++context; s = context; - } - else { - if (!poolAppendChar(&parser->m_tempPool, *s)) + } else { + if (! poolAppendChar(&parser->m_tempPool, *s)) return XML_FALSE; s++; } @@ -6310,8 +6031,7 @@ setContext(XML_Parser parser, const XML_Char *context) } static void FASTCALL -normalizePublicId(XML_Char *publicId) -{ +normalizePublicId(XML_Char *publicId) { XML_Char *p = publicId; XML_Char *s; for (s = publicId; *s; s++) { @@ -6332,8 +6052,7 @@ normalizePublicId(XML_Char *publicId) } static DTD * -dtdCreate(const XML_Memory_Handling_Suite *ms) -{ +dtdCreate(const XML_Memory_Handling_Suite *ms) { DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD)); if (p == NULL) return p; @@ -6365,13 +6084,12 @@ dtdCreate(const XML_Memory_Handling_Suite *ms) } static void -dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) -{ +dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) { HASH_TABLE_ITER iter; hashTableIterInit(&iter, &(p->elementTypes)); for (;;) { ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); - if (!e) + if (! e) break; if (e->allocDefaultAtts != 0) ms->free_fcn(e->defaultAtts); @@ -6407,13 +6125,12 @@ dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) } static void -dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) -{ +dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) { HASH_TABLE_ITER iter; hashTableIterInit(&iter, &(p->elementTypes)); for (;;) { ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); - if (!e) + if (! e) break; if (e->allocDefaultAtts != 0) ms->free_fcn(e->defaultAtts); @@ -6438,8 +6155,8 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) The new DTD has already been initialized. */ static int -dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms) -{ +dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, + const XML_Memory_Handling_Suite *ms) { HASH_TABLE_ITER iter; /* Copy the prefix table. */ @@ -6448,12 +6165,12 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H for (;;) { const XML_Char *name; const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); - if (!oldP) + if (! oldP) break; name = poolCopyString(&(newDtd->pool), oldP->name); - if (!name) + if (! name) return 0; - if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX))) + if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX))) return 0; } @@ -6466,18 +6183,18 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H const XML_Char *name; const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); - if (!oldA) + if (! oldA) break; /* Remember to allocate the scratch byte before the name. */ - if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) + if (! poolAppendChar(&(newDtd->pool), XML_T('\0'))) return 0; name = poolCopyString(&(newDtd->pool), oldA->name); - if (!name) + if (! name) return 0; ++name; newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID)); - if (!newA) + if (! newA) return 0; newA->maybeTokenized = oldA->maybeTokenized; if (oldA->prefix) { @@ -6499,57 +6216,52 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H ELEMENT_TYPE *newE; const XML_Char *name; const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); - if (!oldE) + if (! oldE) break; name = poolCopyString(&(newDtd->pool), oldE->name); - if (!name) + if (! name) return 0; newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE)); - if (!newE) + if (! newE) return 0; if (oldE->nDefaultAtts) { - newE->defaultAtts = (DEFAULT_ATTRIBUTE *) - ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); - if (!newE->defaultAtts) { + newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn( + oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); + if (! newE->defaultAtts) { return 0; } } if (oldE->idAtt) - newE->idAtt = (ATTRIBUTE_ID *) - lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0); + newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), + oldE->idAtt->name, 0); newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; if (oldE->prefix) newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), oldE->prefix->name, 0); for (i = 0; i < newE->nDefaultAtts; i++) { - newE->defaultAtts[i].id = (ATTRIBUTE_ID *) - lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); + newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup( + oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; if (oldE->defaultAtts[i].value) { newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); - if (!newE->defaultAtts[i].value) + if (! newE->defaultAtts[i].value) return 0; - } - else + } else newE->defaultAtts[i].value = NULL; } } /* Copy the entity tables. */ - if (!copyEntityTable(oldParser, - &(newDtd->generalEntities), - &(newDtd->pool), - &(oldDtd->generalEntities))) - return 0; + if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool), + &(oldDtd->generalEntities))) + return 0; #ifdef XML_DTD - if (!copyEntityTable(oldParser, - &(newDtd->paramEntities), - &(newDtd->pool), - &(oldDtd->paramEntities))) - return 0; + if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool), + &(oldDtd->paramEntities))) + return 0; newDtd->paramEntityRead = oldDtd->paramEntityRead; #endif /* XML_DTD */ @@ -6566,14 +6278,11 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H newDtd->scaffIndex = oldDtd->scaffIndex; return 1; -} /* End dtdCopy */ +} /* End dtdCopy */ static int -copyEntityTable(XML_Parser oldParser, - HASH_TABLE *newTable, - STRING_POOL *newPool, - const HASH_TABLE *oldTable) -{ +copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable, + STRING_POOL *newPool, const HASH_TABLE *oldTable) { HASH_TABLE_ITER iter; const XML_Char *cachedOldBase = NULL; const XML_Char *cachedNewBase = NULL; @@ -6584,17 +6293,17 @@ copyEntityTable(XML_Parser oldParser, ENTITY *newE; const XML_Char *name; const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); - if (!oldE) + if (! oldE) break; name = poolCopyString(newPool, oldE->name); - if (!name) + if (! name) return 0; newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY)); - if (!newE) + if (! newE) return 0; if (oldE->systemId) { const XML_Char *tem = poolCopyString(newPool, oldE->systemId); - if (!tem) + if (! tem) return 0; newE->systemId = tem; if (oldE->base) { @@ -6603,29 +6312,28 @@ copyEntityTable(XML_Parser oldParser, else { cachedOldBase = oldE->base; tem = poolCopyString(newPool, cachedOldBase); - if (!tem) + if (! tem) return 0; cachedNewBase = newE->base = tem; } } if (oldE->publicId) { tem = poolCopyString(newPool, oldE->publicId); - if (!tem) + if (! tem) return 0; newE->publicId = tem; } - } - else { - const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, - oldE->textLen); - if (!tem) + } else { + const XML_Char *tem + = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen); + if (! tem) return 0; newE->textPtr = tem; newE->textLen = oldE->textLen; } if (oldE->notation) { const XML_Char *tem = poolCopyString(newPool, oldE->notation); - if (!tem) + if (! tem) return 0; newE->notation = tem; } @@ -6638,8 +6346,7 @@ copyEntityTable(XML_Parser oldParser, #define INIT_POWER 6 static XML_Bool FASTCALL -keyeq(KEY s1, KEY s2) -{ +keyeq(KEY s1, KEY s2) { for (; *s1 == *s2; s1++, s2++) if (*s1 == 0) return XML_TRUE; @@ -6647,23 +6354,21 @@ keyeq(KEY s1, KEY s2) } static size_t -keylen(KEY s) -{ +keylen(KEY s) { size_t len = 0; - for (; *s; s++, len++); + for (; *s; s++, len++) + ; return len; } static void -copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key) -{ +copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) { key->k[0] = 0; key->k[1] = get_hash_secret_salt(parser); } static unsigned long FASTCALL -hash(XML_Parser parser, KEY s) -{ +hash(XML_Parser parser, KEY s) { struct siphash state; struct sipkey key; (void)sip24_valid; @@ -6674,26 +6379,24 @@ hash(XML_Parser parser, KEY s) } static NAMED * -lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) -{ +lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { size_t i; if (table->size == 0) { size_t tsize; - if (!createSize) + if (! createSize) return NULL; table->power = INIT_POWER; /* 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); - if (!table->v) { + if (! table->v) { table->size = 0; return NULL; } memset(table->v, 0, tsize); i = hash(parser, name) & ((unsigned long)table->size - 1); - } - else { + } else { unsigned long h = hash(parser, name); unsigned long mask = (unsigned long)table->size - 1; unsigned char step = 0; @@ -6701,11 +6404,11 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) while (table->v[i]) { if (keyeq(name, table->v[i]->name)) return table->v[i]; - if (!step) + if (! step) step = PROBE_STEP(h, mask, table->power); i < step ? (i += table->size - step) : (i -= step); } - if (!createSize) + if (! createSize) return NULL; /* check for overflow (table is half full) */ @@ -6715,7 +6418,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) unsigned long newMask = (unsigned long)newSize - 1; size_t tsize = newSize * sizeof(NAMED *); NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize); - if (!newV) + if (! newV) return NULL; memset(newV, 0, tsize); for (i = 0; i < table->size; i++) @@ -6724,7 +6427,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) size_t j = newHash & newMask; step = 0; while (newV[j]) { - if (!step) + if (! step) step = PROBE_STEP(newHash, newMask, newPower); j < step ? (j += newSize - step) : (j -= step); } @@ -6737,14 +6440,14 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) i = h & newMask; step = 0; while (table->v[i]) { - if (!step) + if (! step) step = PROBE_STEP(h, newMask, newPower); i < step ? (i += newSize - step) : (i -= step); } } } table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize); - if (!table->v[i]) + if (! table->v[i]) return NULL; memset(table->v[i], 0, createSize); table->v[i]->name = name; @@ -6753,8 +6456,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) } static void FASTCALL -hashTableClear(HASH_TABLE *table) -{ +hashTableClear(HASH_TABLE *table) { size_t i; for (i = 0; i < table->size; i++) { table->mem->free_fcn(table->v[i]); @@ -6764,8 +6466,7 @@ hashTableClear(HASH_TABLE *table) } static void FASTCALL -hashTableDestroy(HASH_TABLE *table) -{ +hashTableDestroy(HASH_TABLE *table) { size_t i; for (i = 0; i < table->size; i++) table->mem->free_fcn(table->v[i]); @@ -6773,8 +6474,7 @@ hashTableDestroy(HASH_TABLE *table) } static void FASTCALL -hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) -{ +hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) { p->power = 0; p->size = 0; p->used = 0; @@ -6783,15 +6483,13 @@ hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) } static void FASTCALL -hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) -{ +hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) { iter->p = table->v; iter->end = iter->p + table->size; } -static NAMED * FASTCALL -hashTableIterNext(HASH_TABLE_ITER *iter) -{ +static NAMED *FASTCALL +hashTableIterNext(HASH_TABLE_ITER *iter) { while (iter->p != iter->end) { NAMED *tem = *(iter->p)++; if (tem) @@ -6801,8 +6499,7 @@ hashTableIterNext(HASH_TABLE_ITER *iter) } static void FASTCALL -poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) -{ +poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) { pool->blocks = NULL; pool->freeBlocks = NULL; pool->start = NULL; @@ -6812,9 +6509,8 @@ poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) } static void FASTCALL -poolClear(STRING_POOL *pool) -{ - if (!pool->freeBlocks) +poolClear(STRING_POOL *pool) { + if (! pool->freeBlocks) pool->freeBlocks = pool->blocks; else { BLOCK *p = pool->blocks; @@ -6832,8 +6528,7 @@ poolClear(STRING_POOL *pool) } static void FASTCALL -poolDestroy(STRING_POOL *pool) -{ +poolDestroy(STRING_POOL *pool) { BLOCK *p = pool->blocks; while (p) { BLOCK *tem = p->next; @@ -6849,26 +6544,26 @@ poolDestroy(STRING_POOL *pool) } static XML_Char * -poolAppend(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end) -{ - if (!pool->ptr && !poolGrow(pool)) +poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr, + const char *end) { + if (! pool->ptr && ! poolGrow(pool)) return NULL; for (;;) { - const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); - if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) + const enum XML_Convert_Result convert_res = XmlConvert( + enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); + if ((convert_res == XML_CONVERT_COMPLETED) + || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; - if (!poolGrow(pool)) + if (! poolGrow(pool)) return NULL; } return pool->start; } -static const XML_Char * FASTCALL -poolCopyString(STRING_POOL *pool, const XML_Char *s) -{ +static const XML_Char *FASTCALL +poolCopyString(STRING_POOL *pool, const XML_Char *s) { do { - if (!poolAppendChar(pool, *s)) + if (! poolAppendChar(pool, *s)) return NULL; } while (*s++); s = pool->start; @@ -6877,9 +6572,8 @@ poolCopyString(STRING_POOL *pool, const XML_Char *s) } static const XML_Char * -poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) -{ - if (!pool->ptr && !poolGrow(pool)) { +poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) { + if (! pool->ptr && ! poolGrow(pool)) { /* The following line is unreachable given the current usage of * poolCopyStringN(). Currently it is called from exactly one * place to copy the text of a simple general entity. By that @@ -6894,7 +6588,7 @@ poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) return NULL; /* LCOV_EXCL_LINE */ } for (; n > 0; --n, s++) { - if (!poolAppendChar(pool, *s)) + if (! poolAppendChar(pool, *s)) return NULL; } s = pool->start; @@ -6902,11 +6596,10 @@ poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) return s; } -static const XML_Char * FASTCALL -poolAppendString(STRING_POOL *pool, const XML_Char *s) -{ +static const XML_Char *FASTCALL +poolAppendString(STRING_POOL *pool, const XML_Char *s) { while (*s) { - if (!poolAppendChar(pool, *s)) + if (! poolAppendChar(pool, *s)) return NULL; s++; } @@ -6914,20 +6607,18 @@ poolAppendString(STRING_POOL *pool, const XML_Char *s) } static XML_Char * -poolStoreString(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end) -{ - if (!poolAppend(pool, enc, ptr, end)) +poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr, + const char *end) { + if (! poolAppend(pool, enc, ptr, end)) return NULL; - if (pool->ptr == pool->end && !poolGrow(pool)) + if (pool->ptr == pool->end && ! poolGrow(pool)) return NULL; *(pool->ptr)++ = 0; return pool->start; } static size_t -poolBytesToAllocateFor(int blockSize) -{ +poolBytesToAllocateFor(int blockSize) { /* Unprotected math would be: ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); ** @@ -6935,7 +6626,7 @@ poolBytesToAllocateFor(int blockSize) ** For a + b * c we check b * c in isolation first, so that addition of a ** on top has no chance of making us accept a small non-negative number */ - const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ + const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ if (blockSize <= 0) return 0; @@ -6945,8 +6636,8 @@ poolBytesToAllocateFor(int blockSize) { const int stretchedBlockSize = blockSize * (int)stretch; - const int bytesToAllocate = (int)( - offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); + const int bytesToAllocate + = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); if (bytesToAllocate < 0) return 0; @@ -6955,8 +6646,7 @@ poolBytesToAllocateFor(int blockSize) } static XML_Bool FASTCALL -poolGrow(STRING_POOL *pool) -{ +poolGrow(STRING_POOL *pool) { if (pool->freeBlocks) { if (pool->start == 0) { pool->blocks = pool->freeBlocks; @@ -6982,7 +6672,7 @@ poolGrow(STRING_POOL *pool) } if (pool->blocks && pool->start == pool->blocks->s) { BLOCK *temp; - int blockSize = (int)((unsigned)(pool->end - pool->start)*2U); + int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U); size_t bytesToAllocate; /* NOTE: Needs to be calculated prior to calling `realloc` @@ -7003,8 +6693,8 @@ poolGrow(STRING_POOL *pool) if (bytesToAllocate == 0) return XML_FALSE; - temp = (BLOCK *) - pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate); + temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks, + (unsigned)bytesToAllocate); if (temp == NULL) return XML_FALSE; pool->blocks = temp; @@ -7012,8 +6702,7 @@ poolGrow(STRING_POOL *pool) pool->ptr = pool->blocks->s + offsetInsideBlock; pool->start = pool->blocks->s; pool->end = pool->start + blockSize; - } - else { + } else { BLOCK *tem; int blockSize = (int)(pool->end - pool->start); size_t bytesToAllocate; @@ -7028,7 +6717,7 @@ poolGrow(STRING_POOL *pool) * function). Either way it isn't readily testable, so we * exclude it from the coverage statistics. */ - return XML_FALSE; /* LCOV_EXCL_LINE */ + return XML_FALSE; /* LCOV_EXCL_LINE */ } if (blockSize < INIT_BLOCK_SIZE) @@ -7046,14 +6735,13 @@ poolGrow(STRING_POOL *pool) return XML_FALSE; tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate); - if (!tem) + if (! tem) return XML_FALSE; tem->size = blockSize; tem->next = pool->blocks; pool->blocks = tem; if (pool->ptr != pool->start) - memcpy(tem->s, pool->start, - (pool->ptr - pool->start) * sizeof(XML_Char)); + memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char)); pool->ptr = tem->s + (pool->ptr - pool->start); pool->start = tem->s; pool->end = tem->s + blockSize; @@ -7062,15 +6750,14 @@ poolGrow(STRING_POOL *pool) } static int FASTCALL -nextScaffoldPart(XML_Parser parser) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ - CONTENT_SCAFFOLD * me; +nextScaffoldPart(XML_Parser parser) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ + CONTENT_SCAFFOLD *me; int next; - if (!dtd->scaffIndex) { + if (! dtd->scaffIndex) { dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int)); - if (!dtd->scaffIndex) + if (! dtd->scaffIndex) return -1; dtd->scaffIndex[0] = 0; } @@ -7078,15 +6765,14 @@ nextScaffoldPart(XML_Parser parser) if (dtd->scaffCount >= dtd->scaffSize) { CONTENT_SCAFFOLD *temp; if (dtd->scaffold) { - temp = (CONTENT_SCAFFOLD *) - REALLOC(parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); + temp = (CONTENT_SCAFFOLD *)REALLOC( + parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); if (temp == NULL) return -1; dtd->scaffSize *= 2; - } - else { + } else { temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS - * sizeof(CONTENT_SCAFFOLD)); + * sizeof(CONTENT_SCAFFOLD)); if (temp == NULL) return -1; dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; @@ -7096,11 +6782,12 @@ nextScaffoldPart(XML_Parser parser) next = dtd->scaffCount++; me = &dtd->scaffold[next]; if (dtd->scaffLevel) { - CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]]; + CONTENT_SCAFFOLD *parent + = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]]; if (parent->lastchild) { dtd->scaffold[parent->lastchild].nextsib = next; } - if (!parent->childcnt) + if (! parent->childcnt) parent->firstchild = next; parent->lastchild = next; parent->childcnt++; @@ -7110,13 +6797,9 @@ nextScaffoldPart(XML_Parser parser) } 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 */ +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) { @@ -7125,21 +6808,19 @@ build_node(XML_Parser parser, src = dtd->scaffold[src_node].name; for (;;) { *(*strpos)++ = *src; - if (!*src) + if (! *src) break; src++; } dest->numchildren = 0; dest->children = NULL; - } - else { + } 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; + 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); } @@ -7148,20 +6829,19 @@ build_node(XML_Parser parser, } static XML_Content * -build_model (XML_Parser parser) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ +build_model(XML_Parser parser) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ XML_Content *ret; XML_Content *cpos; - XML_Char * str; + XML_Char *str; int allocsize = (dtd->scaffCount * sizeof(XML_Content) + (dtd->contentStringLen * sizeof(XML_Char))); ret = (XML_Content *)MALLOC(parser, allocsize); - if (!ret) + if (! ret) return NULL; - str = (XML_Char *) (&ret[dtd->scaffCount]); + str = (XML_Char *)(&ret[dtd->scaffCount]); cpos = &ret[1]; build_node(parser, 0, ret, &cpos, &str); @@ -7169,49 +6849,45 @@ build_model (XML_Parser parser) } static ELEMENT_TYPE * -getElementType(XML_Parser parser, - const ENCODING *enc, - const char *ptr, - const char *end) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ +getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr, + const char *end) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); ELEMENT_TYPE *ret; - if (!name) + if (! name) return NULL; - ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); - if (!ret) + ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, + sizeof(ELEMENT_TYPE)); + if (! ret) return NULL; if (ret->name != name) poolDiscard(&dtd->pool); else { poolFinish(&dtd->pool); - if (!setElementTypePrefix(parser, ret)) + if (! setElementTypePrefix(parser, ret)) return NULL; } return ret; } static XML_Char * -copyString(const XML_Char *s, - const XML_Memory_Handling_Suite *memsuite) -{ - int charsRequired = 0; - XML_Char *result; - - /* First determine how long the string is */ - while (s[charsRequired] != 0) { - charsRequired++; - } - /* Include the terminator */ +copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) { + int charsRequired = 0; + XML_Char *result; + + /* First determine how long the string is */ + while (s[charsRequired] != 0) { charsRequired++; + } + /* Include the terminator */ + charsRequired++; - /* Now allocate space for the copy */ - result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char)); - if (result == NULL) - return NULL; - /* Copy the original into place */ - memcpy(result, s, charsRequired * sizeof(XML_Char)); - return result; + /* Now allocate space for the copy */ + result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char)); + if (result == NULL) + return NULL; + /* Copy the original into place */ + memcpy(result, s, charsRequired * sizeof(XML_Char)); + return result; } diff --git a/Modules/expat/xmlrole.c b/Modules/expat/xmlrole.c index 708507d575be84..4d3e3e86e9e864 100644 --- a/Modules/expat/xmlrole.c +++ b/Modules/expat/xmlrole.c @@ -33,11 +33,11 @@ #include #ifdef _WIN32 -#include "winconfig.h" +# include "winconfig.h" #else -#ifdef HAVE_EXPAT_CONFIG_H -#include -#endif +# ifdef HAVE_EXPAT_CONFIG_H +# include +# endif #endif /* ndef _WIN32 */ #include "expat_external.h" @@ -52,107 +52,88 @@ */ -static const char KW_ANY[] = { - ASCII_A, ASCII_N, ASCII_Y, '\0' }; -static const char KW_ATTLIST[] = { - ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' }; -static const char KW_CDATA[] = { - ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; -static const char KW_DOCTYPE[] = { - ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' }; -static const char KW_ELEMENT[] = { - ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' }; -static const char KW_EMPTY[] = { - ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' }; -static const char KW_ENTITIES[] = { - ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, - '\0' }; -static const char KW_ENTITY[] = { - ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; -static const char KW_FIXED[] = { - ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' }; -static const char KW_ID[] = { - ASCII_I, ASCII_D, '\0' }; -static const char KW_IDREF[] = { - ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; -static const char KW_IDREFS[] = { - ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; +static const char KW_ANY[] = {ASCII_A, ASCII_N, ASCII_Y, '\0'}; +static const char KW_ATTLIST[] + = {ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0'}; +static const char KW_CDATA[] + = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; +static const char KW_DOCTYPE[] + = {ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0'}; +static const char KW_ELEMENT[] + = {ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0'}; +static const char KW_EMPTY[] + = {ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0'}; +static const char KW_ENTITIES[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, + ASCII_I, ASCII_E, ASCII_S, '\0'}; +static const char KW_ENTITY[] + = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'}; +static const char KW_FIXED[] + = {ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0'}; +static const char KW_ID[] = {ASCII_I, ASCII_D, '\0'}; +static const char KW_IDREF[] + = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'}; +static const char KW_IDREFS[] + = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'}; #ifdef XML_DTD -static const char KW_IGNORE[] = { - ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' }; +static const char KW_IGNORE[] + = {ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0'}; #endif -static const char KW_IMPLIED[] = { - ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' }; +static const char KW_IMPLIED[] + = {ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0'}; #ifdef XML_DTD -static const char KW_INCLUDE[] = { - ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' }; +static const char KW_INCLUDE[] + = {ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0'}; #endif -static const char KW_NDATA[] = { - ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; -static const char KW_NMTOKEN[] = { - ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; -static const char KW_NMTOKENS[] = { - ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, - '\0' }; -static const char KW_NOTATION[] = - { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, - '\0' }; -static const char KW_PCDATA[] = { - ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; -static const char KW_PUBLIC[] = { - ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' }; -static const char KW_REQUIRED[] = { - ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, - '\0' }; -static const char KW_SYSTEM[] = { - ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' }; +static const char KW_NDATA[] + = {ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; +static const char KW_NMTOKEN[] + = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'}; +static const char KW_NMTOKENS[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, + ASCII_E, ASCII_N, ASCII_S, '\0'}; +static const char KW_NOTATION[] = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, + ASCII_I, ASCII_O, ASCII_N, '\0'}; +static const char KW_PCDATA[] + = {ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; +static const char KW_PUBLIC[] + = {ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0'}; +static const char KW_REQUIRED[] = {ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, + ASCII_R, ASCII_E, ASCII_D, '\0'}; +static const char KW_SYSTEM[] + = {ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0'}; #ifndef MIN_BYTES_PER_CHAR -#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) +# define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) #endif #ifdef XML_DTD -#define setTopLevel(state) \ - ((state)->handler = ((state)->documentEntity \ - ? internalSubset \ - : externalSubset1)) +# define setTopLevel(state) \ + ((state)->handler \ + = ((state)->documentEntity ? internalSubset : externalSubset1)) #else /* not XML_DTD */ -#define setTopLevel(state) ((state)->handler = internalSubset) +# define setTopLevel(state) ((state)->handler = internalSubset) #endif /* not XML_DTD */ -typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, +typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, int tok, + const char *ptr, const char *end, const ENCODING *enc); -static PROLOG_HANDLER - prolog0, prolog1, prolog2, - doctype0, doctype1, doctype2, doctype3, doctype4, doctype5, - internalSubset, - entity0, entity1, entity2, entity3, entity4, entity5, entity6, - entity7, entity8, entity9, entity10, - notation0, notation1, notation2, notation3, notation4, - attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6, - attlist7, attlist8, attlist9, - element0, element1, element2, element3, element4, element5, element6, - element7, +static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, doctype1, doctype2, + doctype3, doctype4, doctype5, internalSubset, entity0, entity1, entity2, + entity3, entity4, entity5, entity6, entity7, entity8, entity9, entity10, + notation0, notation1, notation2, notation3, notation4, attlist0, attlist1, + attlist2, attlist3, attlist4, attlist5, attlist6, attlist7, attlist8, + attlist9, element0, element1, element2, element3, element4, element5, + element6, element7, #ifdef XML_DTD - externalSubset0, externalSubset1, - condSect0, condSect1, condSect2, + externalSubset0, externalSubset1, condSect0, condSect1, condSect2, #endif /* XML_DTD */ - declClose, - error; + declClose, error; static int FASTCALL common(PROLOG_STATE *state, int tok); static int PTRCALL -prolog0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +prolog0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: state->handler = prolog1; @@ -169,10 +150,8 @@ prolog0(PROLOG_STATE *state, case XML_TOK_BOM: return XML_ROLE_NONE; case XML_TOK_DECL_OPEN: - if (!XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_DOCTYPE)) + if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_DOCTYPE)) break; state->handler = doctype0; return XML_ROLE_DOCTYPE_NONE; @@ -184,12 +163,8 @@ prolog0(PROLOG_STATE *state, } static int PTRCALL -prolog1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +prolog1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; @@ -207,10 +182,8 @@ prolog1(PROLOG_STATE *state, */ return XML_ROLE_NONE; /* LCOV_EXCL_LINE */ case XML_TOK_DECL_OPEN: - if (!XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_DOCTYPE)) + if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_DOCTYPE)) break; state->handler = doctype0; return XML_ROLE_DOCTYPE_NONE; @@ -222,12 +195,11 @@ prolog1(PROLOG_STATE *state, } static int PTRCALL -prolog2(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +prolog2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; @@ -243,12 +215,11 @@ prolog2(PROLOG_STATE *state, } static int PTRCALL -doctype0(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +doctype0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; @@ -261,12 +232,8 @@ doctype0(PROLOG_STATE *state, } static int PTRCALL -doctype1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +doctype1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; @@ -291,12 +258,11 @@ doctype1(PROLOG_STATE *state, } static int PTRCALL -doctype2(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +doctype2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; @@ -308,12 +274,11 @@ doctype2(PROLOG_STATE *state, } static int PTRCALL -doctype3(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +doctype3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; @@ -325,12 +290,11 @@ doctype3(PROLOG_STATE *state, } static int PTRCALL -doctype4(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +doctype4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; @@ -345,12 +309,11 @@ doctype4(PROLOG_STATE *state, } static int PTRCALL -doctype5(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +doctype5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; @@ -362,40 +325,28 @@ doctype5(PROLOG_STATE *state, } static int PTRCALL -internalSubset(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +internalSubset(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_OPEN: - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, + if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_ENTITY)) { state->handler = entity0; return XML_ROLE_ENTITY_NONE; } - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, + if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_ATTLIST)) { state->handler = attlist0; return XML_ROLE_ATTLIST_NONE; } - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, + if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_ELEMENT)) { state->handler = element0; return XML_ROLE_ELEMENT_NONE; } - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, + if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_NOTATION)) { state->handler = notation0; return XML_ROLE_NOTATION_NONE; @@ -419,12 +370,8 @@ internalSubset(PROLOG_STATE *state, #ifdef XML_DTD static int PTRCALL -externalSubset0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +externalSubset0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { state->handler = externalSubset1; if (tok == XML_TOK_XML_DECL) return XML_ROLE_TEXT_DECL; @@ -432,12 +379,8 @@ externalSubset0(PROLOG_STATE *state, } static int PTRCALL -externalSubset1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +externalSubset1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_COND_SECT_OPEN: state->handler = condSect0; @@ -464,12 +407,11 @@ externalSubset1(PROLOG_STATE *state, #endif /* XML_DTD */ static int PTRCALL -entity0(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +entity0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; @@ -484,12 +426,11 @@ entity0(PROLOG_STATE *state, } static int PTRCALL -entity1(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +entity1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; @@ -501,12 +442,8 @@ entity1(PROLOG_STATE *state, } static int PTRCALL -entity2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +entity2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; @@ -529,12 +466,11 @@ entity2(PROLOG_STATE *state, } static int PTRCALL -entity3(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +entity3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; @@ -546,12 +482,11 @@ entity3(PROLOG_STATE *state, } static int PTRCALL -entity4(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +entity4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; @@ -563,12 +498,8 @@ entity4(PROLOG_STATE *state, } static int PTRCALL -entity5(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +entity5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; @@ -586,12 +517,11 @@ entity5(PROLOG_STATE *state, } static int PTRCALL -entity6(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +entity6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; @@ -604,12 +534,8 @@ entity6(PROLOG_STATE *state, } static int PTRCALL -entity7(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +entity7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; @@ -632,12 +558,11 @@ entity7(PROLOG_STATE *state, } static int PTRCALL -entity8(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +entity8(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; @@ -649,12 +574,11 @@ entity8(PROLOG_STATE *state, } static int PTRCALL -entity9(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +entity9(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; @@ -666,12 +590,11 @@ entity9(PROLOG_STATE *state, } static int PTRCALL -entity10(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +entity10(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; @@ -683,12 +606,11 @@ entity10(PROLOG_STATE *state, } static int PTRCALL -notation0(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +notation0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; @@ -700,12 +622,8 @@ notation0(PROLOG_STATE *state, } static int PTRCALL -notation1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +notation1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; @@ -724,12 +642,11 @@ notation1(PROLOG_STATE *state, } static int PTRCALL -notation2(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +notation2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; @@ -741,12 +658,11 @@ notation2(PROLOG_STATE *state, } static int PTRCALL -notation3(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +notation3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; @@ -759,12 +675,11 @@ notation3(PROLOG_STATE *state, } static int PTRCALL -notation4(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +notation4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; @@ -780,12 +695,11 @@ notation4(PROLOG_STATE *state, } static int PTRCALL -attlist0(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +attlist0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; @@ -798,12 +712,11 @@ attlist0(PROLOG_STATE *state, } static int PTRCALL -attlist1(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +attlist1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; @@ -819,34 +732,23 @@ attlist1(PROLOG_STATE *state, } static int PTRCALL -attlist2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +attlist2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; - case XML_TOK_NAME: - { - static const char * const types[] = { - KW_CDATA, - KW_ID, - KW_IDREF, - KW_IDREFS, - KW_ENTITY, - KW_ENTITIES, - KW_NMTOKEN, - KW_NMTOKENS, - }; - int i; - for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++) - if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { - state->handler = attlist8; - return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; - } - } + case XML_TOK_NAME: { + static const char *const types[] = { + KW_CDATA, KW_ID, KW_IDREF, KW_IDREFS, + KW_ENTITY, KW_ENTITIES, KW_NMTOKEN, KW_NMTOKENS, + }; + int i; + for (i = 0; i < (int)(sizeof(types) / sizeof(types[0])); i++) + if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { + state->handler = attlist8; + return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; + } + } if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) { state->handler = attlist5; return XML_ROLE_ATTLIST_NONE; @@ -860,12 +762,11 @@ attlist2(PROLOG_STATE *state, } static int PTRCALL -attlist3(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +attlist3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; @@ -879,12 +780,11 @@ attlist3(PROLOG_STATE *state, } static int PTRCALL -attlist4(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +attlist4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; @@ -899,12 +799,11 @@ attlist4(PROLOG_STATE *state, } static int PTRCALL -attlist5(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +attlist5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; @@ -916,12 +815,11 @@ attlist5(PROLOG_STATE *state, } static int PTRCALL -attlist6(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +attlist6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; @@ -933,12 +831,11 @@ attlist6(PROLOG_STATE *state, } static int PTRCALL -attlist7(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +attlist7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; @@ -954,33 +851,23 @@ attlist7(PROLOG_STATE *state, /* default value */ static int PTRCALL -attlist8(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +attlist8(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_POUND_NAME: - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, + if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, KW_IMPLIED)) { state->handler = attlist1; return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; } - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, + if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, KW_REQUIRED)) { state->handler = attlist1; return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; } - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, + if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, KW_FIXED)) { state->handler = attlist9; return XML_ROLE_ATTLIST_NONE; @@ -994,12 +881,11 @@ attlist8(PROLOG_STATE *state, } static int PTRCALL -attlist9(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +attlist9(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; @@ -1011,12 +897,11 @@ attlist9(PROLOG_STATE *state, } static int PTRCALL -element0(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +element0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; @@ -1029,12 +914,8 @@ element0(PROLOG_STATE *state, } static int PTRCALL -element1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +element1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; @@ -1059,19 +940,13 @@ element1(PROLOG_STATE *state, } static int PTRCALL -element2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +element2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_POUND_NAME: - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, + if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, KW_PCDATA)) { state->handler = element3; return XML_ROLE_CONTENT_PCDATA; @@ -1099,12 +974,11 @@ element2(PROLOG_STATE *state, } static int PTRCALL -element3(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +element3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; @@ -1124,12 +998,11 @@ element3(PROLOG_STATE *state, } static int PTRCALL -element4(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +element4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; @@ -1142,12 +1015,11 @@ element4(PROLOG_STATE *state, } static int PTRCALL -element5(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +element5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; @@ -1163,12 +1035,11 @@ element5(PROLOG_STATE *state, } static int PTRCALL -element6(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +element6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; @@ -1193,12 +1064,11 @@ element6(PROLOG_STATE *state, } static int PTRCALL -element7(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +element7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; @@ -1243,12 +1113,8 @@ element7(PROLOG_STATE *state, #ifdef XML_DTD static int PTRCALL -condSect0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ +condSect0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; @@ -1267,12 +1133,11 @@ condSect0(PROLOG_STATE *state, } static int PTRCALL -condSect1(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +condSect1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; @@ -1285,12 +1150,11 @@ condSect1(PROLOG_STATE *state, } static int PTRCALL -condSect2(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +condSect2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; @@ -1304,12 +1168,11 @@ condSect2(PROLOG_STATE *state, #endif /* XML_DTD */ static int PTRCALL -declClose(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +declClose(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return state->role_none; @@ -1341,21 +1204,21 @@ declClose(PROLOG_STATE *state, * LCOV_EXCL_START */ static int PTRCALL -error(PROLOG_STATE *UNUSED_P(state), - int UNUSED_P(tok), - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ +error(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(state); + UNUSED_P(tok); + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); return XML_ROLE_NONE; } /* LCOV_EXCL_STOP */ static int FASTCALL -common(PROLOG_STATE *state, int tok) -{ +common(PROLOG_STATE *state, int tok) { #ifdef XML_DTD - if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) + if (! state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) return XML_ROLE_INNER_PARAM_ENTITY_REF; #endif state->handler = error; @@ -1363,8 +1226,7 @@ common(PROLOG_STATE *state, int tok) } void -XmlPrologStateInit(PROLOG_STATE *state) -{ +XmlPrologStateInit(PROLOG_STATE *state) { state->handler = prolog0; #ifdef XML_DTD state->documentEntity = 1; @@ -1376,8 +1238,7 @@ XmlPrologStateInit(PROLOG_STATE *state) #ifdef XML_DTD void -XmlPrologStateInitExternalEntity(PROLOG_STATE *state) -{ +XmlPrologStateInitExternalEntity(PROLOG_STATE *state) { state->handler = externalSubset0; state->documentEntity = 0; state->includeLevel = 0; diff --git a/Modules/expat/xmlrole.h b/Modules/expat/xmlrole.h index e5f048eab55c6e..036aba64fd29c6 100644 --- a/Modules/expat/xmlrole.h +++ b/Modules/expat/xmlrole.h @@ -36,7 +36,7 @@ #ifdef __VMS /* 0 1 2 3 0 1 2 3 1234567890123456789012345678901 1234567890123456789012345678901 */ -#define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt +# define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt #endif #include "xmltok.h" @@ -113,11 +113,8 @@ enum { }; typedef struct prolog_state { - int (PTRCALL *handler) (struct prolog_state *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc); + int(PTRCALL *handler)(struct prolog_state *state, int tok, const char *ptr, + const char *end, const ENCODING *enc); unsigned level; int role_none; #ifdef XML_DTD @@ -132,8 +129,8 @@ void XmlPrologStateInit(PROLOG_STATE *); void XmlPrologStateInitExternalEntity(PROLOG_STATE *); #endif /* XML_DTD */ -#define XmlTokenRole(state, tok, ptr, end, enc) \ - (((state)->handler)(state, tok, ptr, end, enc)) +#define XmlTokenRole(state, tok, ptr, end, enc) \ + (((state)->handler)(state, tok, ptr, end, enc)) #ifdef __cplusplus } diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c index 6371a350dadf96..54cfedb85c28c4 100644 --- a/Modules/expat/xmltok.c +++ b/Modules/expat/xmltok.c @@ -30,88 +30,75 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined(_WIN32) && defined(HAVE_EXPAT_CONFIG_H) -# include -#endif +#ifdef _WIN32 +# include "winconfig.h" +#else +# ifdef HAVE_EXPAT_CONFIG_H +# include +# endif +#endif /* ndef _WIN32 */ + #include -#include /* memcpy */ +#include /* memcpy */ #if defined(_MSC_VER) && (_MSC_VER <= 1700) - /* for vs2012/11.0/1700 and earlier Visual Studio compilers */ -# define bool int -# define false 0 -# define true 1 +/* for vs2012/11.0/1700 and earlier Visual Studio compilers */ +# define bool int +# define false 0 +# define true 1 #else -# include +# include #endif - -#ifdef _WIN32 -#include "winconfig.h" -#else -#ifdef HAVE_EXPAT_CONFIG_H -#include -#endif -#endif /* ndef _WIN32 */ - #include "expat_external.h" #include "internal.h" #include "xmltok.h" #include "nametab.h" #ifdef XML_DTD -#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) +# define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) #else -#define IGNORE_SECTION_TOK_VTABLE /* as nothing */ +# define IGNORE_SECTION_TOK_VTABLE /* as nothing */ #endif -#define VTABLE1 \ - { PREFIX(prologTok), PREFIX(contentTok), \ - PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \ - { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ - PREFIX(nameMatchesAscii), \ - PREFIX(nameLength), \ - PREFIX(skipS), \ - PREFIX(getAtts), \ - PREFIX(charRefNumber), \ - PREFIX(predefinedEntityName), \ - PREFIX(updatePosition), \ - PREFIX(isPublicId) +#define VTABLE1 \ + {PREFIX(prologTok), PREFIX(contentTok), \ + PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE}, \ + {PREFIX(attributeValueTok), PREFIX(entityValueTok)}, \ + PREFIX(nameMatchesAscii), PREFIX(nameLength), PREFIX(skipS), \ + PREFIX(getAtts), PREFIX(charRefNumber), PREFIX(predefinedEntityName), \ + PREFIX(updatePosition), PREFIX(isPublicId) #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) -#define UCS2_GET_NAMING(pages, hi, lo) \ - (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F))) +#define UCS2_GET_NAMING(pages, hi, lo) \ + (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo)&0x1F))) /* A 2 byte UTF-8 representation splits the characters 11 bits between the bottom 5 and 6 bits of the bytes. We need 8 bits to index into pages, 3 bits to add to that index and 5 bits to generate the mask. */ -#define UTF8_GET_NAMING2(pages, byte) \ - (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ - + ((((byte)[0]) & 3) << 1) \ - + ((((byte)[1]) >> 5) & 1)] \ - & (1u << (((byte)[1]) & 0x1F))) +#define UTF8_GET_NAMING2(pages, byte) \ + (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + + ((((byte)[0]) & 3) << 1) + ((((byte)[1]) >> 5) & 1)] \ + & (1u << (((byte)[1]) & 0x1F))) /* A 3 byte UTF-8 representation splits the characters 16 bits between the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index into pages, 3 bits to add to that index and 5 bits to generate the mask. */ -#define UTF8_GET_NAMING3(pages, byte) \ - (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \ - + ((((byte)[1]) >> 2) & 0xF)] \ - << 3) \ - + ((((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)) +#define UTF8_GET_NAMING3(pages, byte) \ + (namingBitmap \ + [((pages)[((((byte)[0]) & 0xF) << 4) + ((((byte)[1]) >> 2) & 0xF)] \ + << 3) \ + + ((((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/ @@ -123,88 +110,76 @@ (A & 0xC0) == 0xC0 means A > 0xBF */ -#define UTF8_INVALID2(p) \ +#define UTF8_INVALID2(p) \ ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0) -#define UTF8_INVALID3(p) \ - (((p)[2] & 0x80) == 0 \ - || \ - ((*p) == 0xEF && (p)[1] == 0xBF \ - ? \ - (p)[2] > 0xBD \ - : \ - ((p)[2] & 0xC0) == 0xC0) \ - || \ - ((*p) == 0xE0 \ - ? \ - (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \ - : \ - ((p)[1] & 0x80) == 0 \ - || \ - ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0))) - -#define UTF8_INVALID4(p) \ - (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \ - || \ - ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \ - || \ - ((*p) == 0xF0 \ - ? \ - (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \ - : \ - ((p)[1] & 0x80) == 0 \ - || \ - ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) +#define UTF8_INVALID3(p) \ + (((p)[2] & 0x80) == 0 \ + || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD \ + : ((p)[2] & 0xC0) == 0xC0) \ + || ((*p) == 0xE0 \ + ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \ + : ((p)[1] & 0x80) == 0 \ + || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0))) + +#define UTF8_INVALID4(p) \ + (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 || ((p)[2] & 0x80) == 0 \ + || ((p)[2] & 0xC0) == 0xC0 \ + || ((*p) == 0xF0 \ + ? (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \ + : ((p)[1] & 0x80) == 0 \ + || ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) static int PTRFASTCALL -isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p)) -{ +isNever(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + UNUSED_P(p); return 0; } static int PTRFASTCALL -utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p) -{ +utf8_isName2(const ENCODING *enc, const char *p) { + UNUSED_P(enc); return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); } static int PTRFASTCALL -utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p) -{ +utf8_isName3(const ENCODING *enc, const char *p) { + UNUSED_P(enc); return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); } #define utf8_isName4 isNever static int PTRFASTCALL -utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p) -{ +utf8_isNmstrt2(const ENCODING *enc, const char *p) { + UNUSED_P(enc); return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); } static int PTRFASTCALL -utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p) -{ +utf8_isNmstrt3(const ENCODING *enc, const char *p) { + UNUSED_P(enc); return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); } #define utf8_isNmstrt4 isNever static int PTRFASTCALL -utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p) -{ +utf8_isInvalid2(const ENCODING *enc, const char *p) { + UNUSED_P(enc); return UTF8_INVALID2((const unsigned char *)p); } static int PTRFASTCALL -utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p) -{ +utf8_isInvalid3(const ENCODING *enc, const char *p) { + UNUSED_P(enc); return UTF8_INVALID3((const unsigned char *)p); } static int PTRFASTCALL -utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p) -{ +utf8_isInvalid4(const ENCODING *enc, const char *p) { + UNUSED_P(enc); return UTF8_INVALID4((const unsigned char *)p); } @@ -212,61 +187,44 @@ struct normal_encoding { ENCODING enc; unsigned char type[256]; #ifdef XML_MIN_SIZE - int (PTRFASTCALL *byteType)(const ENCODING *, const char *); - int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *); - int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *); - int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *); - int (PTRCALL *charMatches)(const ENCODING *, const char *, int); + int(PTRFASTCALL *byteType)(const ENCODING *, const char *); + int(PTRFASTCALL *isNameMin)(const ENCODING *, const char *); + int(PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *); + int(PTRFASTCALL *byteToAscii)(const ENCODING *, const char *); + int(PTRCALL *charMatches)(const ENCODING *, const char *, int); #endif /* XML_MIN_SIZE */ - int (PTRFASTCALL *isName2)(const ENCODING *, const char *); - int (PTRFASTCALL *isName3)(const ENCODING *, const char *); - int (PTRFASTCALL *isName4)(const ENCODING *, const char *); - int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *); - int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *); - int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *); - int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *); - int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *); - int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *); + int(PTRFASTCALL *isName2)(const ENCODING *, const char *); + int(PTRFASTCALL *isName3)(const ENCODING *, const char *); + int(PTRFASTCALL *isName4)(const ENCODING *, const char *); + int(PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *); + int(PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *); + int(PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *); + int(PTRFASTCALL *isInvalid2)(const ENCODING *, const char *); + int(PTRFASTCALL *isInvalid3)(const ENCODING *, const char *); + int(PTRFASTCALL *isInvalid4)(const ENCODING *, const char *); }; -#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *) (enc)) +#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc)) #ifdef XML_MIN_SIZE -#define STANDARD_VTABLE(E) \ - E ## byteType, \ - E ## isNameMin, \ - E ## isNmstrtMin, \ - E ## byteToAscii, \ - E ## charMatches, +# define STANDARD_VTABLE(E) \ + E##byteType, E##isNameMin, E##isNmstrtMin, E##byteToAscii, E##charMatches, #else -#define STANDARD_VTABLE(E) /* as nothing */ +# define STANDARD_VTABLE(E) /* as nothing */ #endif -#define NORMAL_VTABLE(E) \ - E ## isName2, \ - E ## isName3, \ - E ## isName4, \ - E ## isNmstrt2, \ - E ## isNmstrt3, \ - E ## isNmstrt4, \ - E ## isInvalid2, \ - E ## isInvalid3, \ - E ## isInvalid4 - -#define NULL_VTABLE \ - /* isName2 */ NULL, \ - /* isName3 */ NULL, \ - /* isName4 */ NULL, \ - /* isNmstrt2 */ NULL, \ - /* isNmstrt3 */ NULL, \ - /* isNmstrt4 */ NULL, \ - /* isInvalid2 */ NULL, \ - /* isInvalid3 */ NULL, \ - /* isInvalid4 */ NULL +#define NORMAL_VTABLE(E) \ + E##isName2, E##isName3, E##isName4, E##isNmstrt2, E##isNmstrt3, \ + E##isNmstrt4, E##isInvalid2, E##isInvalid3, E##isInvalid4 + +#define NULL_VTABLE \ + /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL, \ + /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \ + /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL static int FASTCALL checkCharRefNumber(int); @@ -274,75 +232,70 @@ static int FASTCALL checkCharRefNumber(int); #include "ascii.h" #ifdef XML_MIN_SIZE -#define sb_isNameMin isNever -#define sb_isNmstrtMin isNever +# define sb_isNameMin isNever +# define sb_isNmstrtMin isNever #endif #ifdef XML_MIN_SIZE -#define MINBPC(enc) ((enc)->minBytesPerChar) +# define MINBPC(enc) ((enc)->minBytesPerChar) #else /* minimum bytes per character */ -#define MINBPC(enc) 1 +# define MINBPC(enc) 1 #endif -#define SB_BYTE_TYPE(enc, p) \ +#define SB_BYTE_TYPE(enc, p) \ (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) #ifdef XML_MIN_SIZE static int PTRFASTCALL -sb_byteType(const ENCODING *enc, const char *p) -{ +sb_byteType(const ENCODING *enc, const char *p) { return SB_BYTE_TYPE(enc, p); } -#define BYTE_TYPE(enc, p) \ - (AS_NORMAL_ENCODING(enc)->byteType(enc, p)) +# define BYTE_TYPE(enc, p) (AS_NORMAL_ENCODING(enc)->byteType(enc, p)) #else -#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) +# define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) #endif #ifdef XML_MIN_SIZE -#define BYTE_TO_ASCII(enc, p) \ - (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p)) +# define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p)) static int PTRFASTCALL -sb_byteToAscii(const ENCODING *enc, const char *p) -{ +sb_byteToAscii(const ENCODING *enc, const char *p) { + UNUSED_P(enc); return *p; } #else -#define BYTE_TO_ASCII(enc, p) (*(p)) +# define BYTE_TO_ASCII(enc, p) (*(p)) #endif -#define IS_NAME_CHAR(enc, p, n) \ - (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p)) -#define IS_NMSTRT_CHAR(enc, p, n) \ - (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p)) -#define IS_INVALID_CHAR(enc, p, n) \ - (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p)) +#define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p)) +#define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p)) +#define IS_INVALID_CHAR(enc, p, n) \ + (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) #ifdef XML_MIN_SIZE -#define IS_NAME_CHAR_MINBPC(enc, p) \ - (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p)) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) \ - (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p)) +# define IS_NAME_CHAR_MINBPC(enc, p) \ + (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p)) +# define IS_NMSTRT_CHAR_MINBPC(enc, p) \ + (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p)) #else -#define IS_NAME_CHAR_MINBPC(enc, p) (0) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) +# define IS_NAME_CHAR_MINBPC(enc, p) (0) +# define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) #endif #ifdef XML_MIN_SIZE -#define CHAR_MATCHES(enc, p, c) \ - (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c)) +# define CHAR_MATCHES(enc, p, c) \ + (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c)) static int PTRCALL -sb_charMatches(const ENCODING *enc, const char *p, int c) -{ +sb_charMatches(const ENCODING *enc, const char *p, int c) { + UNUSED_P(enc); return *p == 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 +#define PREFIX(ident) normal_##ident #define XML_TOK_IMPL_C #include "xmltok_impl.c" #undef XML_TOK_IMPL_C @@ -357,42 +310,46 @@ sb_charMatches(const ENCODING *enc, const char *p, int c) #undef IS_NMSTRT_CHAR_MINBPC #undef IS_INVALID_CHAR -enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ - UTF8_cval1 = 0x00, - UTF8_cval2 = 0xc0, - UTF8_cval3 = 0xe0, - UTF8_cval4 = 0xf0 +enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ + UTF8_cval1 = 0x00, + UTF8_cval2 = 0xc0, + UTF8_cval3 = 0xe0, + UTF8_cval4 = 0xf0 }; void -_INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** fromLimRef) -{ - const char * fromLim = *fromLimRef; +_INTERNAL_trim_to_complete_utf8_characters(const char *from, + const char **fromLimRef) { + const char *fromLim = *fromLimRef; size_t walked = 0; for (; fromLim > from; fromLim--, walked++) { const unsigned char prev = (unsigned char)fromLim[-1]; - if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */ + if ((prev & 0xf8u) + == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */ if (walked + 1 >= 4) { fromLim += 4 - 1; break; } else { walked = 0; } - } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */ + } else if ((prev & 0xf0u) + == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */ if (walked + 1 >= 3) { fromLim += 3 - 1; break; } else { walked = 0; } - } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */ + } else if ((prev & 0xe0u) + == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */ if (walked + 1 >= 2) { fromLim += 2 - 1; break; } else { walked = 0; } - } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */ + } else if ((prev & 0x80u) + == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */ break; } } @@ -400,16 +357,15 @@ _INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** from } static enum XML_Convert_Result PTRCALL -utf8_toUtf8(const ENCODING *UNUSED_P(enc), - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ +utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, + char **toP, const char *toLim) { bool input_incomplete = false; bool output_exhausted = false; /* Avoid copying partial characters (due to limited space). */ const ptrdiff_t bytesAvailable = fromLim - *fromP; const ptrdiff_t bytesStorable = toLim - *toP; + UNUSED_P(enc); if (bytesAvailable > bytesStorable) { fromLim = *fromP + bytesStorable; output_exhausted = true; @@ -417,7 +373,7 @@ utf8_toUtf8(const ENCODING *UNUSED_P(enc), /* Avoid copying partial characters (from incomplete input). */ { - const char * const fromLimBefore = fromLim; + const char *const fromLimBefore = fromLim; _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim); if (fromLim < fromLimBefore) { input_incomplete = true; @@ -431,7 +387,7 @@ utf8_toUtf8(const ENCODING *UNUSED_P(enc), *toP += bytesToCopy; } - if (output_exhausted) /* needs to go first */ + if (output_exhausted) /* needs to go first */ return XML_CONVERT_OUTPUT_EXHAUSTED; else if (input_incomplete) return XML_CONVERT_INPUT_INCOMPLETE; @@ -440,10 +396,8 @@ utf8_toUtf8(const ENCODING *UNUSED_P(enc), } static enum XML_Convert_Result PTRCALL -utf8_toUtf16(const ENCODING *enc, - const char **fromP, const char *fromLim, - unsigned short **toP, const unsigned short *toLim) -{ +utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) { enum XML_Convert_Result res = XML_CONVERT_COMPLETED; unsigned short *to = *toP; const char *from = *fromP; @@ -462,30 +416,28 @@ utf8_toUtf16(const ENCODING *enc, res = XML_CONVERT_INPUT_INCOMPLETE; goto after; } - *to++ = (unsigned short)(((from[0] & 0xf) << 12) - | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f)); + *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) + | (from[2] & 0x3f)); from += 3; break; - case BT_LEAD4: - { - unsigned long n; - if (toLim - to < 2) { - res = XML_CONVERT_OUTPUT_EXHAUSTED; - goto after; - } - if (fromLim - from < 4) { - res = XML_CONVERT_INPUT_INCOMPLETE; - goto after; - } - n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) - | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); - n -= 0x10000; - to[0] = (unsigned short)((n >> 10) | 0xD800); - to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); - to += 2; - from += 4; + case BT_LEAD4: { + unsigned long n; + if (toLim - to < 2) { + res = XML_CONVERT_OUTPUT_EXHAUSTED; + goto after; } - break; + if (fromLim - from < 4) { + res = XML_CONVERT_INPUT_INCOMPLETE; + goto after; + } + n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) + | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); + n -= 0x10000; + to[0] = (unsigned short)((n >> 10) | 0xD800); + to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); + to += 2; + from += 4; + } break; default: *to++ = *from++; break; @@ -500,56 +452,51 @@ utf8_toUtf16(const ENCODING *enc, } #ifdef XML_NS -static const struct normal_encoding utf8_encoding_ns = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#include "asciitab.h" -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; +static const struct normal_encoding utf8_encoding_ns + = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, + { +# include "asciitab.h" +# include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; #endif -static const struct normal_encoding utf8_encoding = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { +static const struct normal_encoding utf8_encoding + = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, + { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; #ifdef XML_NS -static const struct normal_encoding internal_utf8_encoding_ns = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#include "iasciitab.h" -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; +static const struct normal_encoding internal_utf8_encoding_ns + = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, + { +# include "iasciitab.h" +# include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; #endif -static const struct normal_encoding internal_utf8_encoding = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { +static const struct normal_encoding internal_utf8_encoding + = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, + { #define BT_COLON BT_NMSTRT #include "iasciitab.h" #undef BT_COLON #include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; static enum XML_Convert_Result PTRCALL -latin1_toUtf8(const ENCODING *UNUSED_P(enc), - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ +latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, + char **toP, const char *toLim) { + UNUSED_P(enc); for (;;) { unsigned char c; if (*fromP == fromLim) @@ -561,8 +508,7 @@ latin1_toUtf8(const ENCODING *UNUSED_P(enc), *(*toP)++ = (char)((c >> 6) | UTF8_cval2); *(*toP)++ = (char)((c & 0x3f) | 0x80); (*fromP)++; - } - else { + } else { if (*toP == toLim) return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = *(*fromP)++; @@ -571,10 +517,9 @@ latin1_toUtf8(const ENCODING *UNUSED_P(enc), } static enum XML_Convert_Result PTRCALL -latin1_toUtf16(const ENCODING *UNUSED_P(enc), - const char **fromP, const char *fromLim, - unsigned short **toP, const unsigned short *toLim) -{ +latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) { + UNUSED_P(enc); while (*fromP < fromLim && *toP < toLim) *(*toP)++ = (unsigned char)*(*fromP)++; @@ -586,33 +531,30 @@ latin1_toUtf16(const ENCODING *UNUSED_P(enc), #ifdef XML_NS -static const struct normal_encoding latin1_encoding_ns = { - { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, - { -#include "asciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(sb_) NULL_VTABLE -}; +static const struct normal_encoding latin1_encoding_ns + = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, + { +# include "asciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(sb_) NULL_VTABLE}; #endif -static const struct normal_encoding latin1_encoding = { - { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, - { +static const struct normal_encoding latin1_encoding + = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, + { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "latin1tab.h" - }, - STANDARD_VTABLE(sb_) NULL_VTABLE -}; + }, + STANDARD_VTABLE(sb_) NULL_VTABLE}; static enum XML_Convert_Result PTRCALL -ascii_toUtf8(const ENCODING *UNUSED_P(enc), - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ +ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, + char **toP, const char *toLim) { + UNUSED_P(enc); while (*fromP < fromLim && *toP < toLim) *(*toP)++ = *(*fromP)++; @@ -624,40 +566,45 @@ ascii_toUtf8(const ENCODING *UNUSED_P(enc), #ifdef XML_NS -static const struct normal_encoding ascii_encoding_ns = { - { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, - { -#include "asciitab.h" -/* BT_NONXML == 0 */ - }, - STANDARD_VTABLE(sb_) NULL_VTABLE -}; +static const struct normal_encoding ascii_encoding_ns + = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, + { +# include "asciitab.h" + /* BT_NONXML == 0 */ + }, + STANDARD_VTABLE(sb_) NULL_VTABLE}; #endif -static const struct normal_encoding ascii_encoding = { - { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, - { +static const struct normal_encoding ascii_encoding + = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, + { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON -/* BT_NONXML == 0 */ - }, - STANDARD_VTABLE(sb_) NULL_VTABLE -}; + /* BT_NONXML == 0 */ + }, + STANDARD_VTABLE(sb_) NULL_VTABLE}; static int PTRFASTCALL -unicode_byte_type(char hi, char lo) -{ +unicode_byte_type(char hi, char lo) { switch ((unsigned char)hi) { - case 0xD8: case 0xD9: case 0xDA: case 0xDB: + /* 0xD800–0xDBFF first 16-bit code unit or high surrogate (W1) */ + case 0xD8: + case 0xD9: + case 0xDA: + case 0xDB: return BT_LEAD4; - case 0xDC: case 0xDD: case 0xDE: case 0xDF: + /* 0xDC00–0xDFFF second 16-bit code unit or low surrogate (W2) */ + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: return BT_TRAIL; case 0xFF: switch ((unsigned char)lo) { - case 0xFF: - case 0xFE: + case 0xFF: /* noncharacter-FFFF */ + case 0xFE: /* noncharacter-FFFE */ return BT_NONXML; } break; @@ -665,102 +612,105 @@ unicode_byte_type(char hi, char lo) return BT_NONASCII; } -#define DEFINE_UTF16_TO_UTF8(E) \ -static enum XML_Convert_Result PTRCALL \ -E ## toUtf8(const ENCODING *UNUSED_P(enc), \ - const char **fromP, const char *fromLim, \ - char **toP, const char *toLim) \ -{ \ - const char *from = *fromP; \ - fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \ - for (; from < fromLim; from += 2) { \ - int plane; \ - unsigned char lo2; \ - unsigned char lo = GET_LO(from); \ - unsigned char hi = GET_HI(from); \ - switch (hi) { \ - case 0: \ - if (lo < 0x80) { \ - if (*toP == toLim) { \ - *fromP = from; \ - return XML_CONVERT_OUTPUT_EXHAUSTED; \ - } \ - *(*toP)++ = lo; \ - break; \ - } \ - /* fall through */ \ - case 0x1: case 0x2: case 0x3: \ - case 0x4: case 0x5: case 0x6: case 0x7: \ - if (toLim - *toP < 2) { \ - *fromP = from; \ - return XML_CONVERT_OUTPUT_EXHAUSTED; \ - } \ - *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ - *(*toP)++ = ((lo & 0x3f) | 0x80); \ - break; \ - default: \ - if (toLim - *toP < 3) { \ - *fromP = from; \ - return XML_CONVERT_OUTPUT_EXHAUSTED; \ - } \ - /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ - *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ - *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ - *(*toP)++ = ((lo & 0x3f) | 0x80); \ - break; \ - case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ - if (toLim - *toP < 4) { \ - *fromP = from; \ - return XML_CONVERT_OUTPUT_EXHAUSTED; \ - } \ - if (fromLim - from < 4) { \ - *fromP = from; \ - return XML_CONVERT_INPUT_INCOMPLETE; \ - } \ - plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ - *(*toP)++ = ((plane >> 2) | UTF8_cval4); \ - *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ - from += 2; \ - lo2 = GET_LO(from); \ - *(*toP)++ = (((lo & 0x3) << 4) \ - | ((GET_HI(from) & 0x3) << 2) \ - | (lo2 >> 6) \ - | 0x80); \ - *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ - break; \ - } \ - } \ - *fromP = from; \ - if (from < fromLim) \ - return XML_CONVERT_INPUT_INCOMPLETE; \ - else \ - return XML_CONVERT_COMPLETED; \ -} +#define DEFINE_UTF16_TO_UTF8(E) \ + static enum XML_Convert_Result PTRCALL E##toUtf8( \ + const ENCODING *enc, const char **fromP, const char *fromLim, \ + char **toP, const char *toLim) { \ + const char *from = *fromP; \ + UNUSED_P(enc); \ + fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \ + for (; from < fromLim; from += 2) { \ + int plane; \ + unsigned char lo2; \ + unsigned char lo = GET_LO(from); \ + unsigned char hi = GET_HI(from); \ + switch (hi) { \ + case 0: \ + if (lo < 0x80) { \ + if (*toP == toLim) { \ + *fromP = from; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + *(*toP)++ = lo; \ + break; \ + } \ + /* fall through */ \ + case 0x1: \ + case 0x2: \ + case 0x3: \ + case 0x4: \ + case 0x5: \ + case 0x6: \ + case 0x7: \ + if (toLim - *toP < 2) { \ + *fromP = from; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ + *(*toP)++ = ((lo & 0x3f) | 0x80); \ + break; \ + default: \ + if (toLim - *toP < 3) { \ + *fromP = from; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ + *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ + *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ + *(*toP)++ = ((lo & 0x3f) | 0x80); \ + break; \ + case 0xD8: \ + case 0xD9: \ + case 0xDA: \ + case 0xDB: \ + if (toLim - *toP < 4) { \ + *fromP = from; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + if (fromLim - from < 4) { \ + *fromP = from; \ + return XML_CONVERT_INPUT_INCOMPLETE; \ + } \ + plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ + *(*toP)++ = (char)((plane >> 2) | UTF8_cval4); \ + *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ + from += 2; \ + lo2 = GET_LO(from); \ + *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2) \ + | (lo2 >> 6) | 0x80); \ + *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ + break; \ + } \ + } \ + *fromP = from; \ + if (from < fromLim) \ + return XML_CONVERT_INPUT_INCOMPLETE; \ + else \ + return XML_CONVERT_COMPLETED; \ + } -#define DEFINE_UTF16_TO_UTF16(E) \ -static enum XML_Convert_Result PTRCALL \ -E ## toUtf16(const ENCODING *UNUSED_P(enc), \ - const char **fromP, const char *fromLim, \ - unsigned short **toP, const unsigned short *toLim) \ -{ \ - enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \ - fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \ - /* Avoid copying first half only of surrogate */ \ - if (fromLim - *fromP > ((toLim - *toP) << 1) \ - && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \ - fromLim -= 2; \ - res = XML_CONVERT_INPUT_INCOMPLETE; \ - } \ - for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \ - *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ - if ((*toP == toLim) && (*fromP < fromLim)) \ - return XML_CONVERT_OUTPUT_EXHAUSTED; \ - else \ - return res; \ -} +#define DEFINE_UTF16_TO_UTF16(E) \ + static enum XML_Convert_Result PTRCALL E##toUtf16( \ + const ENCODING *enc, const char **fromP, const char *fromLim, \ + unsigned short **toP, const unsigned short *toLim) { \ + enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \ + UNUSED_P(enc); \ + fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \ + /* Avoid copying first half only of surrogate */ \ + if (fromLim - *fromP > ((toLim - *toP) << 1) \ + && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \ + fromLim -= 2; \ + res = XML_CONVERT_INPUT_INCOMPLETE; \ + } \ + for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \ + *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ + if ((*toP == toLim) && (*fromP < fromLim)) \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + else \ + return res; \ + } -#define SET2(ptr, ch) \ - (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8))) +#define SET2(ptr, ch) (((ptr)[0] = ((ch)&0xff)), ((ptr)[1] = ((ch) >> 8))) #define GET_LO(ptr) ((unsigned char)(ptr)[0]) #define GET_HI(ptr) ((unsigned char)(ptr)[1]) @@ -771,8 +721,7 @@ DEFINE_UTF16_TO_UTF16(little2_) #undef GET_LO #undef GET_HI -#define SET2(ptr, ch) \ - (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF))) +#define SET2(ptr, ch) (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch)&0xFF))) #define GET_LO(ptr) ((unsigned char)(ptr)[1]) #define GET_HI(ptr) ((unsigned char)(ptr)[0]) @@ -783,292 +732,279 @@ DEFINE_UTF16_TO_UTF16(big2_) #undef GET_LO #undef GET_HI -#define LITTLE2_BYTE_TYPE(enc, p) \ - ((p)[1] == 0 \ - ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ - : unicode_byte_type((p)[1], (p)[0])) -#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1) -#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c) -#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \ +#define LITTLE2_BYTE_TYPE(enc, p) \ + ((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_IS_NAME_CHAR_MINBPC(p) \ UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) -#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ +#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) \ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) #ifdef XML_MIN_SIZE static int PTRFASTCALL -little2_byteType(const ENCODING *enc, const char *p) -{ +little2_byteType(const ENCODING *enc, const char *p) { return LITTLE2_BYTE_TYPE(enc, p); } static int PTRFASTCALL -little2_byteToAscii(const ENCODING *enc, const char *p) -{ - return LITTLE2_BYTE_TO_ASCII(enc, p); +little2_byteToAscii(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return LITTLE2_BYTE_TO_ASCII(p); } static int PTRCALL -little2_charMatches(const ENCODING *enc, const char *p, int c) -{ - return LITTLE2_CHAR_MATCHES(enc, p, c); +little2_charMatches(const ENCODING *enc, const char *p, int c) { + UNUSED_P(enc); + return LITTLE2_CHAR_MATCHES(p, c); } static int PTRFASTCALL -little2_isNameMin(const ENCODING *enc, const char *p) -{ - return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p); +little2_isNameMin(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return LITTLE2_IS_NAME_CHAR_MINBPC(p); } static int PTRFASTCALL -little2_isNmstrtMin(const ENCODING *enc, const char *p) -{ - return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p); +little2_isNmstrtMin(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p); } -#undef VTABLE -#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 +# undef VTABLE +# define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 #else /* not XML_MIN_SIZE */ -#undef PREFIX -#define PREFIX(ident) little2_ ## ident -#define MINBPC(enc) 2 +# undef PREFIX +# define PREFIX(ident) little2_##ident +# define MINBPC(enc) 2 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ -#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) -#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) -#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c) -#define IS_NAME_CHAR(enc, p, n) 0 -#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) -#define IS_NMSTRT_CHAR(enc, p, n) (0) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) - -#define XML_TOK_IMPL_C -#include "xmltok_impl.c" -#undef XML_TOK_IMPL_C - -#undef MINBPC -#undef BYTE_TYPE -#undef BYTE_TO_ASCII -#undef CHAR_MATCHES -#undef IS_NAME_CHAR -#undef IS_NAME_CHAR_MINBPC -#undef IS_NMSTRT_CHAR -#undef IS_NMSTRT_CHAR_MINBPC -#undef IS_INVALID_CHAR +# define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) +# define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p) +# define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c) +# define IS_NAME_CHAR(enc, p, n) 0 +# define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p) +# define IS_NMSTRT_CHAR(enc, p, n) (0) +# define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) + +# define XML_TOK_IMPL_C +# include "xmltok_impl.c" +# undef XML_TOK_IMPL_C + +# undef MINBPC +# undef BYTE_TYPE +# undef BYTE_TO_ASCII +# undef CHAR_MATCHES +# undef IS_NAME_CHAR +# undef IS_NAME_CHAR_MINBPC +# undef IS_NMSTRT_CHAR +# undef IS_NMSTRT_CHAR_MINBPC +# undef IS_INVALID_CHAR #endif /* not XML_MIN_SIZE */ #ifdef XML_NS -static const struct normal_encoding little2_encoding_ns = { - { VTABLE, 2, 0, -#if BYTEORDER == 1234 - 1 -#else - 0 -#endif - }, - { -#include "asciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) NULL_VTABLE -}; +static const struct normal_encoding little2_encoding_ns + = {{VTABLE, 2, 0, +# if BYTEORDER == 1234 + 1 +# else + 0 +# endif + }, + { +# include "asciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_VTABLE}; #endif -static const struct normal_encoding little2_encoding = { - { VTABLE, 2, 0, +static const struct normal_encoding little2_encoding + = {{VTABLE, 2, 0, #if BYTEORDER == 1234 - 1 + 1 #else - 0 + 0 #endif - }, - { + }, + { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) NULL_VTABLE -}; + }, + STANDARD_VTABLE(little2_) NULL_VTABLE}; #if BYTEORDER != 4321 -#ifdef XML_NS +# ifdef XML_NS -static const struct normal_encoding internal_little2_encoding_ns = { - { VTABLE, 2, 0, 1 }, - { -#include "iasciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) NULL_VTABLE -}; +static const struct normal_encoding internal_little2_encoding_ns + = {{VTABLE, 2, 0, 1}, + { +# include "iasciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_VTABLE}; -#endif +# endif -static const struct normal_encoding internal_little2_encoding = { - { VTABLE, 2, 0, 1 }, - { -#define BT_COLON BT_NMSTRT -#include "iasciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) NULL_VTABLE -}; +static const struct normal_encoding internal_little2_encoding + = {{VTABLE, 2, 0, 1}, + { +# define BT_COLON BT_NMSTRT +# include "iasciitab.h" +# undef BT_COLON +# include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_VTABLE}; #endif - -#define BIG2_BYTE_TYPE(enc, p) \ - ((p)[0] == 0 \ - ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ - : unicode_byte_type((p)[0], (p)[1])) -#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1) -#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c) -#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \ +#define BIG2_BYTE_TYPE(enc, p) \ + ((p)[0] == 0 \ + ? ((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_IS_NAME_CHAR_MINBPC(p) \ UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) -#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ +#define BIG2_IS_NMSTRT_CHAR_MINBPC(p) \ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) #ifdef XML_MIN_SIZE static int PTRFASTCALL -big2_byteType(const ENCODING *enc, const char *p) -{ +big2_byteType(const ENCODING *enc, const char *p) { return BIG2_BYTE_TYPE(enc, p); } static int PTRFASTCALL -big2_byteToAscii(const ENCODING *enc, const char *p) -{ - return BIG2_BYTE_TO_ASCII(enc, p); +big2_byteToAscii(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return BIG2_BYTE_TO_ASCII(p); } static int PTRCALL -big2_charMatches(const ENCODING *enc, const char *p, int c) -{ - return BIG2_CHAR_MATCHES(enc, p, c); +big2_charMatches(const ENCODING *enc, const char *p, int c) { + UNUSED_P(enc); + return BIG2_CHAR_MATCHES(p, c); } static int PTRFASTCALL -big2_isNameMin(const ENCODING *enc, const char *p) -{ - return BIG2_IS_NAME_CHAR_MINBPC(enc, p); +big2_isNameMin(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return BIG2_IS_NAME_CHAR_MINBPC(p); } static int PTRFASTCALL -big2_isNmstrtMin(const ENCODING *enc, const char *p) -{ - return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p); +big2_isNmstrtMin(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return BIG2_IS_NMSTRT_CHAR_MINBPC(p); } -#undef VTABLE -#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 +# undef VTABLE +# define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 #else /* not XML_MIN_SIZE */ -#undef PREFIX -#define PREFIX(ident) big2_ ## ident -#define MINBPC(enc) 2 +# undef PREFIX +# define PREFIX(ident) big2_##ident +# define MINBPC(enc) 2 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ -#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) -#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) -#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c) -#define IS_NAME_CHAR(enc, p, n) 0 -#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p) -#define IS_NMSTRT_CHAR(enc, p, n) (0) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) - -#define XML_TOK_IMPL_C -#include "xmltok_impl.c" -#undef XML_TOK_IMPL_C - -#undef MINBPC -#undef BYTE_TYPE -#undef BYTE_TO_ASCII -#undef CHAR_MATCHES -#undef IS_NAME_CHAR -#undef IS_NAME_CHAR_MINBPC -#undef IS_NMSTRT_CHAR -#undef IS_NMSTRT_CHAR_MINBPC -#undef IS_INVALID_CHAR +# define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) +# define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p) +# define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c) +# define IS_NAME_CHAR(enc, p, n) 0 +# define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p) +# define IS_NMSTRT_CHAR(enc, p, n) (0) +# define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p) + +# define XML_TOK_IMPL_C +# include "xmltok_impl.c" +# undef XML_TOK_IMPL_C + +# undef MINBPC +# undef BYTE_TYPE +# undef BYTE_TO_ASCII +# undef CHAR_MATCHES +# undef IS_NAME_CHAR +# undef IS_NAME_CHAR_MINBPC +# undef IS_NMSTRT_CHAR +# undef IS_NMSTRT_CHAR_MINBPC +# undef IS_INVALID_CHAR #endif /* not XML_MIN_SIZE */ #ifdef XML_NS -static const struct normal_encoding big2_encoding_ns = { - { VTABLE, 2, 0, -#if BYTEORDER == 4321 - 1 -#else - 0 -#endif - }, - { -#include "asciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) NULL_VTABLE -}; +static const struct normal_encoding big2_encoding_ns + = {{VTABLE, 2, 0, +# if BYTEORDER == 4321 + 1 +# else + 0 +# endif + }, + { +# include "asciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_VTABLE}; #endif -static const struct normal_encoding big2_encoding = { - { VTABLE, 2, 0, +static const struct normal_encoding big2_encoding + = {{VTABLE, 2, 0, #if BYTEORDER == 4321 - 1 + 1 #else - 0 + 0 #endif - }, - { + }, + { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) NULL_VTABLE -}; + }, + STANDARD_VTABLE(big2_) NULL_VTABLE}; #if BYTEORDER != 1234 -#ifdef XML_NS +# ifdef XML_NS -static const struct normal_encoding internal_big2_encoding_ns = { - { VTABLE, 2, 0, 1 }, - { -#include "iasciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) NULL_VTABLE -}; +static const struct normal_encoding internal_big2_encoding_ns + = {{VTABLE, 2, 0, 1}, + { +# include "iasciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_VTABLE}; -#endif +# endif -static const struct normal_encoding internal_big2_encoding = { - { VTABLE, 2, 0, 1 }, - { -#define BT_COLON BT_NMSTRT -#include "iasciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) NULL_VTABLE -}; +static const struct normal_encoding internal_big2_encoding + = {{VTABLE, 2, 0, 1}, + { +# define BT_COLON BT_NMSTRT +# include "iasciitab.h" +# undef BT_COLON +# include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_VTABLE}; #endif #undef PREFIX static int FASTCALL -streqci(const char *s1, const char *s2) -{ +streqci(const char *s1, const char *s2) { for (;;) { char c1 = *s1++; char c2 = *s2++; @@ -1082,22 +1018,21 @@ streqci(const char *s1, const char *s2) c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */ if (c1 != c2) return 0; - if (!c1) + if (! c1) break; } return 1; } static void PTRCALL -initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr, - const char *end, POSITION *pos) -{ +initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end, + POSITION *pos) { + UNUSED_P(enc); normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); } static int -toAscii(const ENCODING *enc, const char *ptr, const char *end) -{ +toAscii(const ENCODING *enc, const char *ptr, const char *end) { char buf[1]; char *p = buf; XmlUtf8Convert(enc, &ptr, end, &p, p + 1); @@ -1108,8 +1043,7 @@ toAscii(const ENCODING *enc, const char *ptr, const char *end) } static int FASTCALL -isSpace(int c) -{ +isSpace(int c) { switch (c) { case 0x20: case 0xD: @@ -1124,21 +1058,16 @@ isSpace(int c) followed by name=val. */ static int -parsePseudoAttribute(const ENCODING *enc, - const char *ptr, - const char *end, - const char **namePtr, - const char **nameEndPtr, - const char **valPtr, - const char **nextTokPtr) -{ +parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end, + const char **namePtr, const char **nameEndPtr, + const char **valPtr, const char **nextTokPtr) { int c; char open; if (ptr == end) { *namePtr = NULL; return 1; } - if (!isSpace(toAscii(enc, ptr, end))) { + if (! isSpace(toAscii(enc, ptr, end))) { *nextTokPtr = ptr; return 0; } @@ -1194,12 +1123,9 @@ parsePseudoAttribute(const ENCODING *enc, c = toAscii(enc, ptr, end); if (c == open) break; - if (!(ASCII_a <= c && c <= ASCII_z) - && !(ASCII_A <= c && c <= ASCII_Z) - && !(ASCII_0 <= c && c <= ASCII_9) - && c != ASCII_PERIOD - && c != ASCII_MINUS - && c != ASCII_UNDERSCORE) { + if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z) + && ! (ASCII_0 <= c && c <= ASCII_9) && c != ASCII_PERIOD + && c != ASCII_MINUS && c != ASCII_UNDERSCORE) { *nextTokPtr = ptr; return 0; } @@ -1208,68 +1134,52 @@ parsePseudoAttribute(const ENCODING *enc, return 1; } -static const char KW_version[] = { - ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0' -}; +static const char KW_version[] + = {ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'}; -static const char KW_encoding[] = { - ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0' -}; +static const char KW_encoding[] = {ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, + ASCII_i, ASCII_n, ASCII_g, '\0'}; -static const char KW_standalone[] = { - ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, - ASCII_n, ASCII_e, '\0' -}; +static const char KW_standalone[] + = {ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, + ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'}; -static const char KW_yes[] = { - ASCII_y, ASCII_e, ASCII_s, '\0' -}; +static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, '\0'}; -static const char KW_no[] = { - ASCII_n, ASCII_o, '\0' -}; +static const char KW_no[] = {ASCII_n, ASCII_o, '\0'}; static int -doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, - const char *, +doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *, const char *), - int isGeneralTextEntity, - const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr, - const char **versionPtr, - const char **versionEndPtr, - const char **encodingName, - const ENCODING **encoding, - int *standalone) -{ + int isGeneralTextEntity, const ENCODING *enc, const char *ptr, + const char *end, const char **badPtr, const char **versionPtr, + const char **versionEndPtr, const char **encodingName, + const ENCODING **encoding, int *standalone) { const char *val = NULL; const char *name = NULL; const char *nameEnd = NULL; ptr += 5 * enc->minBytesPerChar; end -= 2 * enc->minBytesPerChar; - if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) - || !name) { + if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) + || ! name) { *badPtr = ptr; return 0; } - if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { - if (!isGeneralTextEntity) { + if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { + if (! isGeneralTextEntity) { *badPtr = name; return 0; } - } - else { + } else { if (versionPtr) *versionPtr = val; if (versionEndPtr) *versionEndPtr = ptr; - if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { + if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { *badPtr = ptr; return 0; } - if (!name) { + if (! name) { if (isGeneralTextEntity) { /* a TextDecl must have an EncodingDecl */ *badPtr = ptr; @@ -1280,7 +1190,7 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, } if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { int c = toAscii(enc, val, end); - if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) { + if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)) { *badPtr = val; return 0; } @@ -1288,14 +1198,14 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, *encodingName = val; if (encoding) *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); - if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { + if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { *badPtr = ptr; return 0; } - if (!name) + if (! name) return 1; } - if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) + if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) || isGeneralTextEntity) { *badPtr = name; return 0; @@ -1303,12 +1213,10 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { if (standalone) *standalone = 1; - } - else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { + } else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { if (standalone) *standalone = 0; - } - else { + } else { *badPtr = val; return 0; } @@ -1322,11 +1230,16 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, } static int FASTCALL -checkCharRefNumber(int result) -{ +checkCharRefNumber(int result) { switch (result >> 8) { - case 0xD8: case 0xD9: case 0xDA: case 0xDB: - case 0xDC: case 0xDD: case 0xDE: case 0xDF: + case 0xD8: + case 0xD9: + case 0xDA: + case 0xDB: + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: return -1; case 0: if (latin1_encoding.type[result] == BT_NONXML) @@ -1341,8 +1254,7 @@ checkCharRefNumber(int result) } int FASTCALL -XmlUtf8Encode(int c, char *buf) -{ +XmlUtf8Encode(int c, char *buf) { enum { /* minN is minimum legal resulting value for N byte sequence */ min2 = 0x80, @@ -1378,8 +1290,7 @@ XmlUtf8Encode(int c, char *buf) } int FASTCALL -XmlUtf16Encode(int charNum, unsigned short *buf) -{ +XmlUtf16Encode(int charNum, unsigned short *buf) { if (charNum < 0) return 0; if (charNum < 0x10000) { @@ -1403,17 +1314,15 @@ struct unknown_encoding { char utf8[256][4]; }; -#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *) (enc)) +#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *)(enc)) int -XmlSizeOfUnknownEncoding(void) -{ +XmlSizeOfUnknownEncoding(void) { return sizeof(struct unknown_encoding); } static int PTRFASTCALL -unknown_isName(const ENCODING *enc, const char *p) -{ +unknown_isName(const ENCODING *enc, const char *p) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); int c = uenc->convert(uenc->userData, p); if (c & ~0xFFFF) @@ -1422,8 +1331,7 @@ unknown_isName(const ENCODING *enc, const char *p) } static int PTRFASTCALL -unknown_isNmstrt(const ENCODING *enc, const char *p) -{ +unknown_isNmstrt(const ENCODING *enc, const char *p) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); int c = uenc->convert(uenc->userData, p); if (c & ~0xFFFF) @@ -1432,18 +1340,15 @@ unknown_isNmstrt(const ENCODING *enc, const char *p) } static int PTRFASTCALL -unknown_isInvalid(const ENCODING *enc, const char *p) -{ +unknown_isInvalid(const ENCODING *enc, const char *p) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); int c = uenc->convert(uenc->userData, p); return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; } static enum XML_Convert_Result PTRCALL -unknown_toUtf8(const ENCODING *enc, - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ +unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, + char **toP, const char *toLim) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); char buf[XML_UTF8_ENCODE_MAX]; for (;;) { @@ -1461,8 +1366,7 @@ unknown_toUtf8(const ENCODING *enc, utf8 = buf; *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - (BT_LEAD2 - 2)); - } - else { + } else { if (n > toLim - *toP) return XML_CONVERT_OUTPUT_EXHAUSTED; (*fromP)++; @@ -1473,20 +1377,16 @@ unknown_toUtf8(const ENCODING *enc, } static enum XML_Convert_Result PTRCALL -unknown_toUtf16(const ENCODING *enc, - const char **fromP, const char *fromLim, - unsigned short **toP, const unsigned short *toLim) -{ +unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); while (*fromP < fromLim && *toP < toLim) { unsigned short c = uenc->utf16[(unsigned char)**fromP]; if (c == 0) { - c = (unsigned short) - uenc->convert(uenc->userData, *fromP); + c = (unsigned short)uenc->convert(uenc->userData, *fromP); *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - (BT_LEAD2 - 2)); - } - else + } else (*fromP)++; *(*toP)++ = c; } @@ -1498,19 +1398,14 @@ unknown_toUtf16(const ENCODING *enc, } ENCODING * -XmlInitUnknownEncoding(void *mem, - int *table, - CONVERTER convert, - void *userData) -{ +XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert, + void *userData) { int i; struct unknown_encoding *e = (struct unknown_encoding *)mem; - for (i = 0; i < (int)sizeof(struct normal_encoding); i++) - ((char *)mem)[i] = ((char *)&latin1_encoding)[i]; + memcpy(mem, &latin1_encoding, sizeof(struct normal_encoding)); for (i = 0; i < 128; i++) if (latin1_encoding.type[i] != BT_OTHER - && latin1_encoding.type[i] != BT_NONXML - && table[i] != i) + && latin1_encoding.type[i] != BT_NONXML && table[i] != i) return 0; for (i = 0; i < 256; i++) { int c = table[i]; @@ -1520,35 +1415,30 @@ XmlInitUnknownEncoding(void *mem, e->utf16[i] = 0xFFFF; e->utf8[i][0] = 1; e->utf8[i][1] = 0; - } - else if (c < 0) { + } else if (c < 0) { if (c < -4) return 0; /* Multi-byte sequences need a converter function */ - if (!convert) + if (! convert) return 0; e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2)); e->utf8[i][0] = 0; e->utf16[i] = 0; - } - else if (c < 0x80) { + } else if (c < 0x80) { if (latin1_encoding.type[c] != BT_OTHER - && latin1_encoding.type[c] != BT_NONXML - && c != i) + && latin1_encoding.type[c] != BT_NONXML && c != i) return 0; e->normal.type[i] = latin1_encoding.type[c]; e->utf8[i][0] = 1; e->utf8[i][1] = (char)c; e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c); - } - else if (checkCharRefNumber(c) < 0) { + } else if (checkCharRefNumber(c) < 0) { e->normal.type[i] = BT_NONXML; /* This shouldn't really get used. */ e->utf16[i] = 0xFFFF; e->utf8[i][0] = 1; e->utf8[i][1] = 0; - } - else { + } else { if (c > 0xFFFF) return 0; if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) @@ -1593,44 +1483,32 @@ enum { NO_ENC }; -static const char KW_ISO_8859_1[] = { - ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, - ASCII_MINUS, ASCII_1, '\0' -}; -static const char KW_US_ASCII[] = { - ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, - '\0' -}; -static const char KW_UTF_8[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0' -}; -static const char KW_UTF_16[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0' -}; -static const char KW_UTF_16BE[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, - '\0' -}; -static const char KW_UTF_16LE[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, - '\0' -}; +static const char KW_ISO_8859_1[] + = {ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, + ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'}; +static const char KW_US_ASCII[] + = {ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, + ASCII_C, ASCII_I, ASCII_I, '\0'}; +static const char KW_UTF_8[] + = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'}; +static const char KW_UTF_16[] + = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'}; +static const char KW_UTF_16BE[] + = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, + ASCII_6, ASCII_B, ASCII_E, '\0'}; +static const char KW_UTF_16LE[] + = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, + ASCII_6, ASCII_L, ASCII_E, '\0'}; static int FASTCALL -getEncodingIndex(const char *name) -{ - static const char * const encodingNames[] = { - KW_ISO_8859_1, - KW_US_ASCII, - KW_UTF_8, - KW_UTF_16, - KW_UTF_16BE, - KW_UTF_16LE, +getEncodingIndex(const char *name) { + static const char *const encodingNames[] = { + KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE, }; int i; if (name == NULL) return NO_ENC; - for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++) + for (i = 0; i < (int)(sizeof(encodingNames) / sizeof(encodingNames[0])); i++) if (streqci(name, encodingNames[i])) return i; return UNKNOWN_ENC; @@ -1650,15 +1528,9 @@ getEncodingIndex(const char *name) XML_PROLOG_STATE otherwise. */ - static int -initScan(const ENCODING * const *encodingTable, - const INIT_ENCODING *enc, - int state, - const char *ptr, - const char *end, - const char **nextTokPtr) -{ +initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc, + int state, const char *ptr, const char *end, const char **nextTokPtr) { const ENCODING **encPtr; if (ptr >= end) @@ -1683,20 +1555,17 @@ initScan(const ENCODING * const *encodingTable, case 0xFE: case 0xFF: case 0xEF: /* possibly first byte of UTF-8 BOM */ - if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC - && state == XML_CONTENT_STATE) + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) break; /* fall through */ case 0x00: case 0x3C: return XML_TOK_PARTIAL; } - } - else { + } else { switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { case 0xFEFF: - if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC - && state == XML_CONTENT_STATE) + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) break; *nextTokPtr = ptr + 2; *encPtr = encodingTable[UTF_16BE_ENC]; @@ -1710,8 +1579,7 @@ initScan(const ENCODING * const *encodingTable, *encPtr = encodingTable[UTF_16LE_ENC]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); case 0xFFFE: - if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC - && state == XML_CONTENT_STATE) + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) break; *nextTokPtr = ptr + 2; *encPtr = encodingTable[UTF_16LE_ENC]; @@ -1726,8 +1594,8 @@ initScan(const ENCODING * const *encodingTable, */ if (state == XML_CONTENT_STATE) { int e = INIT_ENC_INDEX(enc); - if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC - || e == UTF_16LE_ENC || e == UTF_16_ENC) + if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC + || e == UTF_16_ENC) break; } if (ptr + 2 == end) @@ -1750,8 +1618,7 @@ initScan(const ENCODING * const *encodingTable, break; *encPtr = encodingTable[UTF_16BE_ENC]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); - } - else if (ptr[1] == '\0') { + } else if (ptr[1] == '\0') { /* We could recover here in the case: - parsing an external entity - second byte is 0 @@ -1773,7 +1640,6 @@ initScan(const ENCODING * const *encodingTable, return XmlTok(*encPtr, state, ptr, end, nextTokPtr); } - #define NS(x) x #define ns(x) x #define XML_TOK_NS_C @@ -1784,22 +1650,19 @@ initScan(const ENCODING * const *encodingTable, #ifdef XML_NS -#define NS(x) x ## NS -#define ns(x) x ## _ns +# define NS(x) x##NS +# define ns(x) x##_ns -#define XML_TOK_NS_C -#include "xmltok_ns.c" -#undef XML_TOK_NS_C +# define XML_TOK_NS_C +# include "xmltok_ns.c" +# undef XML_TOK_NS_C -#undef NS -#undef ns +# undef NS +# undef ns ENCODING * -XmlInitUnknownEncodingNS(void *mem, - int *table, - CONVERTER convert, - void *userData) -{ +XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert, + void *userData) { ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); if (enc) ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; diff --git a/Modules/expat/xmltok.h b/Modules/expat/xmltok.h index 50926f38ab323e..2adbf5307befae 100644 --- a/Modules/expat/xmltok.h +++ b/Modules/expat/xmltok.h @@ -38,16 +38,18 @@ extern "C" { #endif /* The following token may be returned by XmlContentTok */ -#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be - start of illegal ]]> sequence */ +#define XML_TOK_TRAILING_RSQB \ + -5 /* ] or ]] at the end of the scan; might be \ + start of illegal ]]> sequence */ /* The following tokens may be returned by both XmlPrologTok and XmlContentTok. */ -#define XML_TOK_NONE -4 /* The string to be scanned is empty */ -#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan; - might be part of CRLF sequence */ -#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ -#define XML_TOK_PARTIAL -1 /* only part of a token */ +#define XML_TOK_NONE -4 /* The string to be scanned is empty */ +#define XML_TOK_TRAILING_CR \ + -3 /* A CR at the end of the scan; \ + might be part of CRLF sequence */ +#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ +#define XML_TOK_PARTIAL -1 /* only part of a token */ #define XML_TOK_INVALID 0 /* The following tokens are returned by XmlContentTok; some are also @@ -62,24 +64,24 @@ extern "C" { #define XML_TOK_DATA_NEWLINE 7 #define XML_TOK_CDATA_SECT_OPEN 8 #define XML_TOK_ENTITY_REF 9 -#define XML_TOK_CHAR_REF 10 /* numeric character reference */ +#define XML_TOK_CHAR_REF 10 /* numeric character reference */ /* The following tokens may be returned by both XmlPrologTok and XmlContentTok. */ -#define XML_TOK_PI 11 /* processing instruction */ -#define XML_TOK_XML_DECL 12 /* XML decl or text decl */ +#define XML_TOK_PI 11 /* processing instruction */ +#define XML_TOK_XML_DECL 12 /* XML decl or text decl */ #define XML_TOK_COMMENT 13 -#define XML_TOK_BOM 14 /* Byte order mark */ +#define XML_TOK_BOM 14 /* Byte order mark */ /* The following tokens are returned only by XmlPrologTok */ #define XML_TOK_PROLOG_S 15 -#define XML_TOK_DECL_OPEN 16 /* */ +#define XML_TOK_DECL_OPEN 16 /* */ #define XML_TOK_NAME 18 #define XML_TOK_NMTOKEN 19 -#define XML_TOK_POUND_NAME 20 /* #name */ -#define XML_TOK_OR 21 /* | */ +#define XML_TOK_POUND_NAME 20 /* #name */ +#define XML_TOK_OR 21 /* | */ #define XML_TOK_PERCENT 22 #define XML_TOK_OPEN_PAREN 23 #define XML_TOK_CLOSE_PAREN 24 @@ -90,14 +92,14 @@ extern "C" { #define XML_TOK_INSTANCE_START 29 /* The following occur only in element type declarations */ -#define XML_TOK_NAME_QUESTION 30 /* name? */ -#define XML_TOK_NAME_ASTERISK 31 /* name* */ -#define XML_TOK_NAME_PLUS 32 /* name+ */ -#define XML_TOK_COND_SECT_OPEN 33 /* */ -#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ -#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ -#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ +#define XML_TOK_NAME_QUESTION 30 /* name? */ +#define XML_TOK_NAME_ASTERISK 31 /* name* */ +#define XML_TOK_NAME_PLUS 32 /* name+ */ +#define XML_TOK_COND_SECT_OPEN 33 /* */ +#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ +#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ +#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ #define XML_TOK_COMMA 38 /* The following token is returned only by XmlAttributeValueTok */ @@ -112,20 +114,20 @@ extern "C" { #define XML_TOK_PREFIXED_NAME 41 #ifdef XML_DTD -#define XML_TOK_IGNORE_SECT 42 +# define XML_TOK_IGNORE_SECT 42 #endif /* XML_DTD */ #ifdef XML_DTD -#define XML_N_STATES 4 +# define XML_N_STATES 4 #else /* not XML_DTD */ -#define XML_N_STATES 3 +# define XML_N_STATES 3 #endif /* not XML_DTD */ #define XML_PROLOG_STATE 0 #define XML_CONTENT_STATE 1 #define XML_CDATA_SECTION_STATE 2 #ifdef XML_DTD -#define XML_IGNORE_SECTION_STATE 3 +# define XML_IGNORE_SECTION_STATE 3 #endif /* XML_DTD */ #define XML_N_LITERAL_TYPES 2 @@ -153,52 +155,41 @@ typedef struct { struct encoding; typedef struct encoding ENCODING; -typedef int (PTRCALL *SCANNER)(const ENCODING *, - const char *, - const char *, - const char **); +typedef int(PTRCALL *SCANNER)(const ENCODING *, const char *, const char *, + const char **); enum XML_Convert_Result { XML_CONVERT_COMPLETED = 0, XML_CONVERT_INPUT_INCOMPLETE = 1, - XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining as well */ + XML_CONVERT_OUTPUT_EXHAUSTED + = 2 /* and therefore potentially input remaining as well */ }; struct encoding { SCANNER scanners[XML_N_STATES]; SCANNER literalScanners[XML_N_LITERAL_TYPES]; - int (PTRCALL *nameMatchesAscii)(const ENCODING *, - const char *, - const char *, - const char *); - int (PTRFASTCALL *nameLength)(const ENCODING *, const char *); + int(PTRCALL *nameMatchesAscii)(const ENCODING *, const char *, const char *, + const char *); + int(PTRFASTCALL *nameLength)(const ENCODING *, const char *); const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *); - int (PTRCALL *getAtts)(const ENCODING *enc, - const char *ptr, - int attsMax, - ATTRIBUTE *atts); - int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr); - int (PTRCALL *predefinedEntityName)(const ENCODING *, - const char *, - const char *); - void (PTRCALL *updatePosition)(const ENCODING *, - const char *ptr, - const char *end, - POSITION *); - int (PTRCALL *isPublicId)(const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr); - enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc, - const char **fromP, - const char *fromLim, - char **toP, - const char *toLim); - enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc, - const char **fromP, - const char *fromLim, - unsigned short **toP, - const unsigned short *toLim); + int(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, int attsMax, + ATTRIBUTE *atts); + int(PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr); + int(PTRCALL *predefinedEntityName)(const ENCODING *, const char *, + const char *); + void(PTRCALL *updatePosition)(const ENCODING *, const char *ptr, + const char *end, POSITION *); + int(PTRCALL *isPublicId)(const ENCODING *enc, const char *ptr, + const char *end, const char **badPtr); + enum XML_Convert_Result(PTRCALL *utf8Convert)(const ENCODING *enc, + const char **fromP, + const char *fromLim, char **toP, + const char *toLim); + enum XML_Convert_Result(PTRCALL *utf16Convert)(const ENCODING *enc, + const char **fromP, + const char *fromLim, + unsigned short **toP, + const unsigned short *toLim); int minBytesPerChar; char isUtf8; char isUtf16; @@ -225,66 +216,62 @@ struct encoding { the prolog outside literals, comments and processing instructions. */ - -#define XmlTok(enc, state, ptr, end, nextTokPtr) \ +#define XmlTok(enc, state, ptr, end, nextTokPtr) \ (((enc)->scanners[state])(enc, ptr, end, nextTokPtr)) -#define XmlPrologTok(enc, ptr, end, nextTokPtr) \ - XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) +#define XmlPrologTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) -#define XmlContentTok(enc, ptr, end, nextTokPtr) \ - XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) +#define XmlContentTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) -#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ - XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) +#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) #ifdef XML_DTD -#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ - XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) +# define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) #endif /* XML_DTD */ /* This is used for performing a 2nd-level tokenization on the content of a literal that has already been returned by XmlTok. */ -#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ +#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) -#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ - XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) +#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ + XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) -#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ - XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) +#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ + XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) -#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ +#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) -#define XmlNameLength(enc, ptr) \ - (((enc)->nameLength)(enc, ptr)) +#define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr)) -#define XmlSkipS(enc, ptr) \ - (((enc)->skipS)(enc, ptr)) +#define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr)) -#define XmlGetAttributes(enc, ptr, attsMax, atts) \ +#define XmlGetAttributes(enc, ptr, attsMax, atts) \ (((enc)->getAtts)(enc, ptr, attsMax, atts)) -#define XmlCharRefNumber(enc, ptr) \ - (((enc)->charRefNumber)(enc, ptr)) +#define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr)) -#define XmlPredefinedEntityName(enc, ptr, end) \ +#define XmlPredefinedEntityName(enc, ptr, end) \ (((enc)->predefinedEntityName)(enc, ptr, end)) -#define XmlUpdatePosition(enc, ptr, end, pos) \ +#define XmlUpdatePosition(enc, ptr, end, pos) \ (((enc)->updatePosition)(enc, ptr, end, pos)) -#define XmlIsPublicId(enc, ptr, end, badPtr) \ +#define XmlIsPublicId(enc, ptr, end, badPtr) \ (((enc)->isPublicId)(enc, ptr, end, badPtr)) -#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ +#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim)) -#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ +#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim)) typedef struct { @@ -292,16 +279,11 @@ typedef struct { const ENCODING **encPtr; } INIT_ENCODING; -int XmlParseXmlDecl(int isGeneralTextEntity, - const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr, - const char **versionPtr, - const char **versionEndPtr, +int XmlParseXmlDecl(int isGeneralTextEntity, const ENCODING *enc, + const char *ptr, const char *end, const char **badPtr, + const char **versionPtr, const char **versionEndPtr, const char **encodingNamePtr, - const ENCODING **namedEncodingPtr, - int *standalonePtr); + const ENCODING **namedEncodingPtr, int *standalonePtr); int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name); const ENCODING *XmlGetUtf8InternalEncoding(void); @@ -310,34 +292,22 @@ int FASTCALL XmlUtf8Encode(int charNumber, char *buf); int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf); int XmlSizeOfUnknownEncoding(void); +typedef int(XMLCALL *CONVERTER)(void *userData, const char *p); -typedef int (XMLCALL *CONVERTER) (void *userData, const char *p); - -ENCODING * -XmlInitUnknownEncoding(void *mem, - int *table, - CONVERTER convert, - void *userData); +ENCODING *XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert, + void *userData); -int XmlParseXmlDeclNS(int isGeneralTextEntity, - const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr, - const char **versionPtr, - const char **versionEndPtr, +int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc, + const char *ptr, const char *end, const char **badPtr, + const char **versionPtr, const char **versionEndPtr, const char **encodingNamePtr, - const ENCODING **namedEncodingPtr, - int *standalonePtr); + const ENCODING **namedEncodingPtr, int *standalonePtr); int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name); const ENCODING *XmlGetUtf8InternalEncodingNS(void); const ENCODING *XmlGetUtf16InternalEncodingNS(void); -ENCODING * -XmlInitUnknownEncodingNS(void *mem, - int *table, - CONVERTER convert, - void *userData); +ENCODING *XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert, + void *userData); #ifdef __cplusplus } #endif diff --git a/Modules/expat/xmltok_impl.c b/Modules/expat/xmltok_impl.c index 4d9ae7dc3896b8..c209221cd79d13 100644 --- a/Modules/expat/xmltok_impl.c +++ b/Modules/expat/xmltok_impl.c @@ -32,130 +32,124 @@ #ifdef XML_TOK_IMPL_C -#ifndef IS_INVALID_CHAR -#define IS_INVALID_CHAR(enc, ptr, n) (0) -#endif - -#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ - 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; \ - } \ - ptr += n; \ - break; +# ifndef IS_INVALID_CHAR +# define IS_INVALID_CHAR(enc, ptr, n) (0) +# endif + +# define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ + 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; \ + } \ + ptr += n; \ + break; -#define INVALID_CASES(ptr, nextTokPtr) \ - INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ - INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ - INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ - case BT_NONXML: \ - case BT_MALFORM: \ - case BT_TRAIL: \ - *(nextTokPtr) = (ptr); \ +# define INVALID_CASES(ptr, nextTokPtr) \ + INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ + INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ + INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ + case BT_NONXML: \ + case BT_MALFORM: \ + case BT_TRAIL: \ + *(nextTokPtr) = (ptr); \ return XML_TOK_INVALID; -#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (!IS_NAME_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - ptr += n; \ - break; - -#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ - case BT_NONASCII: \ - if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - /* fall through */ \ - case BT_NMSTRT: \ - case BT_HEX: \ - case BT_DIGIT: \ - case BT_NAME: \ - case BT_MINUS: \ - ptr += MINBPC(enc); \ - break; \ - CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ - CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ - CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) - -#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - ptr += n; \ - break; - -#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ - case BT_NONASCII: \ - if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - /* fall through */ \ - case BT_NMSTRT: \ - case BT_HEX: \ - ptr += MINBPC(enc); \ - break; \ - CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ - CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ - CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) - -#ifndef PREFIX -#define PREFIX(ident) ident -#endif - - -#define HAS_CHARS(enc, ptr, end, count) \ - (end - ptr >= count * MINBPC(enc)) +# define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (! IS_NAME_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; -#define HAS_CHAR(enc, ptr, end) \ - HAS_CHARS(enc, ptr, end, 1) +# define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ + case BT_NONASCII: \ + if (! IS_NAME_CHAR_MINBPC(enc, ptr)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + /* fall through */ \ + case BT_NMSTRT: \ + case BT_HEX: \ + case BT_DIGIT: \ + case BT_NAME: \ + case BT_MINUS: \ + ptr += MINBPC(enc); \ + break; \ + CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ + CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ + CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) + +# define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (! IS_NMSTRT_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; -#define REQUIRE_CHARS(enc, ptr, end, count) \ - { \ - if (! HAS_CHARS(enc, ptr, end, count)) { \ - return XML_TOK_PARTIAL; \ - } \ +# define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ + case BT_NONASCII: \ + if (! IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + /* fall through */ \ + case BT_NMSTRT: \ + case BT_HEX: \ + ptr += MINBPC(enc); \ + break; \ + CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ + CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ + CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) + +# ifndef PREFIX +# define PREFIX(ident) ident +# endif + +# define HAS_CHARS(enc, ptr, end, count) (end - ptr >= count * MINBPC(enc)) + +# define HAS_CHAR(enc, ptr, end) HAS_CHARS(enc, ptr, end, 1) + +# define REQUIRE_CHARS(enc, ptr, end, count) \ + { \ + if (! HAS_CHARS(enc, ptr, end, count)) { \ + return XML_TOK_PARTIAL; \ + } \ } -#define REQUIRE_CHAR(enc, ptr, end) \ - REQUIRE_CHARS(enc, ptr, end, 1) - +# define REQUIRE_CHAR(enc, ptr, end) REQUIRE_CHARS(enc, ptr, end, 1) /* ptr points to character following " */ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { - case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: + case BT_S: + case BT_CR: + case BT_LF: + case BT_PERCNT: *nextTokPtr = ptr; return XML_TOK_INVALID; } /* fall through */ - case BT_S: case BT_CR: case BT_LF: + case BT_S: + case BT_CR: + case BT_LF: *nextTokPtr = ptr; return XML_TOK_DECL_OPEN; case BT_NMSTRT: @@ -220,12 +218,12 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, } static int PTRCALL -PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr, - const char *end, int *tokPtr) -{ +PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, + int *tokPtr) { int upper = 0; + UNUSED_P(enc); *tokPtr = XML_TOK_PI; - if (end - ptr != MINBPC(enc)*3) + if (end - ptr != MINBPC(enc) * 3) return 1; switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_x: @@ -265,30 +263,31 @@ PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr, /* ptr points to character following "= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { @@ -361,11 +359,11 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, case BT_RSQB: ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); - if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) + if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB)) break; ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { + if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr -= MINBPC(enc); break; } @@ -381,23 +379,25 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, case BT_LF: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; - INVALID_CASES(ptr, nextTokPtr) + INVALID_CASES(ptr, nextTokPtr) default: ptr += MINBPC(enc); break; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_DATA_CHARS; \ - } \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE case BT_NONXML: case BT_MALFORM: case BT_TRAIL: @@ -418,23 +418,26 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, /* ptr points to character following "= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { @@ -842,48 +843,50 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; - if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) + if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB)) break; ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { + if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr -= MINBPC(enc); break; } *nextTokPtr = ptr; return XML_TOK_INVALID; - INVALID_CASES(ptr, nextTokPtr) + INVALID_CASES(ptr, nextTokPtr) default: ptr += MINBPC(enc); break; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_DATA_CHARS; \ - } \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE case BT_RSQB: if (HAS_CHARS(enc, ptr, end, 2)) { - if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { - ptr += MINBPC(enc); - break; - } - if (HAS_CHARS(enc, ptr, end, 3)) { - if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) { - ptr += MINBPC(enc); - break; - } - *nextTokPtr = ptr + 2*MINBPC(enc); - return XML_TOK_INVALID; - } + if (! CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { + ptr += MINBPC(enc); + break; + } + if (HAS_CHARS(enc, ptr, end, 3)) { + if (! CHAR_MATCHES(enc, ptr + 2 * MINBPC(enc), ASCII_GT)) { + ptr += MINBPC(enc); + break; + } + *nextTokPtr = ptr + 2 * MINBPC(enc); + return XML_TOK_INVALID; + } } /* fall through */ case BT_AMP: @@ -908,12 +911,14 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, static int PTRCALL PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ + const char **nextTokPtr) { REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_S: + case BT_LF: + case BT_CR: + case BT_PERCNT: *nextTokPtr = ptr; return XML_TOK_PERCENT; default: @@ -922,7 +927,7 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_PARAM_ENTITY_REF; @@ -936,20 +941,24 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, static int PTRCALL PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ + const char **nextTokPtr) { REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_CR: case BT_LF: case BT_S: - case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_CR: + case BT_LF: + case BT_S: + case BT_RPAR: + case BT_GT: + case BT_PERCNT: + case BT_VERBAR: *nextTokPtr = ptr; return XML_TOK_POUND_NAME; default: @@ -961,14 +970,12 @@ PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, } static int PTRCALL -PREFIX(scanLit)(int open, const ENCODING *enc, - const char *ptr, const char *end, - const char **nextTokPtr) -{ +PREFIX(scanLit)(int open, const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { while (HAS_CHAR(enc, ptr, end)) { int t = BYTE_TYPE(enc, ptr); switch (t) { - INVALID_CASES(ptr, nextTokPtr) + INVALID_CASES(ptr, nextTokPtr) case BT_QUOT: case BT_APOS: ptr += MINBPC(enc); @@ -978,8 +985,12 @@ PREFIX(scanLit)(int open, const ENCODING *enc, return -XML_TOK_LITERAL; *nextTokPtr = ptr; switch (BYTE_TYPE(enc, ptr)) { - case BT_S: case BT_CR: case BT_LF: - case BT_GT: case BT_PERCNT: case BT_LSQB: + case BT_S: + case BT_CR: + case BT_LF: + case BT_GT: + case BT_PERCNT: + case BT_LSQB: return XML_TOK_LITERAL; default: return XML_TOK_INVALID; @@ -994,8 +1005,7 @@ PREFIX(scanLit)(int open, const ENCODING *enc, static int PTRCALL PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ + const char **nextTokPtr) { int tok; if (ptr >= end) return XML_TOK_NONE; @@ -1013,27 +1023,26 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_APOS: return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_LT: - { - ptr += MINBPC(enc); - REQUIRE_CHAR(enc, ptr, end); - switch (BYTE_TYPE(enc, ptr)) { - case BT_EXCL: - return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_QUEST: - return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_NMSTRT: - case BT_HEX: - case BT_NONASCII: - case BT_LEAD2: - case BT_LEAD3: - case BT_LEAD4: - *nextTokPtr = ptr - MINBPC(enc); - return XML_TOK_INSTANCE_START; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; + case BT_LT: { + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + switch (BYTE_TYPE(enc, ptr)) { + case BT_EXCL: + return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_QUEST: + return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_NMSTRT: + case BT_HEX: + case BT_NONASCII: + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + *nextTokPtr = ptr - MINBPC(enc); + return XML_TOK_INSTANCE_START; } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } case BT_CR: if (ptr + MINBPC(enc) == end) { *nextTokPtr = end; @@ -1041,13 +1050,15 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return -XML_TOK_PROLOG_S; } /* fall through */ - case BT_S: case BT_LF: + case BT_S: + case BT_LF: for (;;) { ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) break; switch (BYTE_TYPE(enc, ptr)) { - case BT_S: case BT_LF: + case BT_S: + case BT_LF: break; case BT_CR: /* don't split CR/LF pair */ @@ -1076,7 +1087,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { REQUIRE_CHARS(enc, ptr, end, 2); if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { - *nextTokPtr = ptr + 2*MINBPC(enc); + *nextTokPtr = ptr + 2 * MINBPC(enc); return XML_TOK_COND_SECT_CLOSE; } } @@ -1099,8 +1110,12 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_PLUS: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CLOSE_PAREN_PLUS; - case BT_CR: case BT_LF: case BT_S: - case BT_GT: case BT_COMMA: case BT_VERBAR: + case BT_CR: + case BT_LF: + case BT_S: + case BT_GT: + case BT_COMMA: + case BT_VERBAR: case BT_RPAR: *nextTokPtr = ptr; return XML_TOK_CLOSE_PAREN; @@ -1115,24 +1130,26 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return XML_TOK_DECL_CLOSE; case BT_NUM: return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NAME; \ - break; \ - } \ - if (IS_NAME_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NMTOKEN; \ - break; \ - } \ - *nextTokPtr = ptr; \ +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NAME; \ + break; \ + } \ + if (IS_NAME_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NMTOKEN; \ + break; \ + } \ + *nextTokPtr = ptr; \ return XML_TOK_INVALID; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE case BT_NMSTRT: case BT_HEX: tok = XML_TOK_NAME; @@ -1141,9 +1158,9 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_DIGIT: case BT_NAME: case BT_MINUS: -#ifdef XML_NS +# ifdef XML_NS case BT_COLON: -#endif +# endif tok = XML_TOK_NMTOKEN; ptr += MINBPC(enc); break; @@ -1165,13 +1182,19 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_GT: case BT_RPAR: case BT_COMMA: - case BT_VERBAR: case BT_LSQB: case BT_PERCNT: - case BT_S: case BT_CR: case BT_LF: + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_GT: + case BT_RPAR: + case BT_COMMA: + case BT_VERBAR: + case BT_LSQB: + case BT_PERCNT: + case BT_S: + case BT_CR: + case BT_LF: *nextTokPtr = ptr; return tok; -#ifdef XML_NS +# ifdef XML_NS case BT_COLON: ptr += MINBPC(enc); switch (tok) { @@ -1179,7 +1202,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, REQUIRE_CHAR(enc, ptr, end); tok = XML_TOK_PREFIXED_NAME; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) default: tok = XML_TOK_NMTOKEN; break; @@ -1190,23 +1213,23 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, break; } break; -#endif +# endif case BT_PLUS: - if (tok == XML_TOK_NMTOKEN) { + if (tok == XML_TOK_NMTOKEN) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_NAME_PLUS; case BT_AST: - if (tok == XML_TOK_NMTOKEN) { + if (tok == XML_TOK_NMTOKEN) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_NAME_ASTERISK; case BT_QUEST: - if (tok == XML_TOK_NMTOKEN) { + if (tok == XML_TOK_NMTOKEN) { *nextTokPtr = ptr; return XML_TOK_INVALID; } @@ -1221,9 +1244,8 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, } static int PTRCALL -PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ +PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { const char *start; if (ptr >= end) return XML_TOK_NONE; @@ -1238,10 +1260,14 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, start = ptr; while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: ptr += n; break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE case BT_AMP: if (ptr == start) return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); @@ -1287,9 +1313,8 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, } static int PTRCALL -PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ +PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { const char *start; if (ptr >= end) return XML_TOK_NONE; @@ -1304,10 +1329,14 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, start = ptr; while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: ptr += n; break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE case BT_AMP: if (ptr == start) return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); @@ -1315,8 +1344,7 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, return XML_TOK_DATA_CHARS; case BT_PERCNT: if (ptr == start) { - int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc), - end, nextTokPtr); + int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok; } *nextTokPtr = ptr; @@ -1349,12 +1377,11 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, return XML_TOK_DATA_CHARS; } -#ifdef XML_DTD +# ifdef XML_DTD static int PTRCALL -PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ +PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { int level = 0; if (MINBPC(enc) > 1) { size_t n = end - ptr; @@ -1365,7 +1392,7 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr) + INVALID_CASES(ptr, nextTokPtr) case BT_LT: ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); @@ -1402,12 +1429,11 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, return XML_TOK_PARTIAL; } -#endif /* XML_DTD */ +# endif /* XML_DTD */ static int PTRCALL PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, - const char **badPtr) -{ + const char **badPtr) { ptr += MINBPC(enc); end -= MINBPC(enc); for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { @@ -1430,9 +1456,9 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, case BT_AST: case BT_PERCNT: case BT_NUM: -#ifdef XML_NS +# ifdef XML_NS case BT_COLON: -#endif +# endif break; case BT_S: if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { @@ -1442,7 +1468,7 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, break; case BT_NAME: case BT_NMSTRT: - if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f)) + if (! (BYTE_TO_ASCII(enc, ptr) & ~0x7f)) break; /* fall through */ default: @@ -1466,9 +1492,8 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, */ static int PTRCALL -PREFIX(getAtts)(const ENCODING *enc, const char *ptr, - int attsMax, ATTRIBUTE *atts) -{ +PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax, + ATTRIBUTE *atts) { enum { other, inName, inValue } state = inName; int nAtts = 0; int open = 0; /* defined when state == inValue; @@ -1476,32 +1501,35 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr, for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { -#define START_NAME \ - if (state == other) { \ - if (nAtts < attsMax) { \ - atts[nAtts].name = ptr; \ - atts[nAtts].normalized = 1; \ - } \ - state = inName; \ - } -#define LEAD_CASE(n) \ - case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE +# define START_NAME \ + if (state == other) { \ + if (nAtts < attsMax) { \ + atts[nAtts].name = ptr; \ + atts[nAtts].normalized = 1; \ + } \ + state = inName; \ + } +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + START_NAME ptr += (n - MINBPC(enc)); \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE case BT_NONASCII: case BT_NMSTRT: case BT_HEX: START_NAME break; -#undef START_NAME +# undef START_NAME case BT_QUOT: if (state != inValue) { if (nAtts < attsMax) atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_QUOT; - } - else if (open == BT_QUOT) { + } else if (open == BT_QUOT) { state = other; if (nAtts < attsMax) atts[nAtts].valueEnd = ptr; @@ -1514,8 +1542,7 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr, atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_APOS; - } - else if (open == BT_APOS) { + } else if (open == BT_APOS) { state = other; if (nAtts < attsMax) atts[nAtts].valueEnd = ptr; @@ -1529,16 +1556,15 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr, case BT_S: if (state == inName) state = other; - else if (state == inValue - && nAtts < attsMax - && atts[nAtts].normalized + else if (state == inValue && nAtts < attsMax && atts[nAtts].normalized && (ptr == atts[nAtts].valuePtr || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) atts[nAtts].normalized = 0; break; - case BT_CR: case BT_LF: + case BT_CR: + case BT_LF: /* This case ensures that the first attribute name is counted Apart from that we could just change state on the quote. */ if (state == inName) @@ -1559,29 +1585,44 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr, } static int PTRFASTCALL -PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr) -{ +PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) { int result = 0; /* skip &# */ - ptr += 2*MINBPC(enc); + UNUSED_P(enc); + ptr += 2 * MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_x)) { - for (ptr += MINBPC(enc); - !CHAR_MATCHES(enc, ptr, ASCII_SEMI); + for (ptr += MINBPC(enc); ! CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { int c = BYTE_TO_ASCII(enc, ptr); switch (c) { - case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4: - case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9: + case ASCII_0: + case ASCII_1: + case ASCII_2: + case ASCII_3: + case ASCII_4: + case ASCII_5: + case ASCII_6: + case ASCII_7: + case ASCII_8: + case ASCII_9: result <<= 4; result |= (c - ASCII_0); break; - case ASCII_A: case ASCII_B: case ASCII_C: - case ASCII_D: case ASCII_E: case ASCII_F: + case ASCII_A: + case ASCII_B: + case ASCII_C: + case ASCII_D: + case ASCII_E: + case ASCII_F: result <<= 4; result += 10 + (c - ASCII_A); break; - case ASCII_a: case ASCII_b: case ASCII_c: - case ASCII_d: case ASCII_e: case ASCII_f: + case ASCII_a: + case ASCII_b: + case ASCII_c: + case ASCII_d: + case ASCII_e: + case ASCII_f: result <<= 4; result += 10 + (c - ASCII_a); break; @@ -1589,9 +1630,8 @@ PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr) if (result >= 0x110000) return -1; } - } - else { - for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { + } else { + for (; ! CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { int c = BYTE_TO_ASCII(enc, ptr); result *= 10; result += (c - ASCII_0); @@ -1603,10 +1643,10 @@ PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr) } static int PTRCALL -PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr, - const char *end) -{ - switch ((end - ptr)/MINBPC(enc)) { +PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, + const char *end) { + UNUSED_P(enc); + switch ((end - ptr) / MINBPC(enc)) { case 2: if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { switch (BYTE_TO_ASCII(enc, ptr)) { @@ -1657,9 +1697,9 @@ PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr, } static int PTRCALL -PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1, - const char *end1, const char *ptr2) -{ +PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, + const char *end1, const char *ptr2) { + UNUSED_P(enc); for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { if (end1 - ptr1 < MINBPC(enc)) { /* This line cannot be executed. The incoming data has already @@ -1669,27 +1709,30 @@ PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1, */ return 0; /* LCOV_EXCL_LINE */ } - if (!CHAR_MATCHES(enc, ptr1, *ptr2)) + if (! CHAR_MATCHES(enc, ptr1, *ptr2)) return 0; } return ptr1 == end1; } static int PTRFASTCALL -PREFIX(nameLength)(const ENCODING *enc, const char *ptr) -{ +PREFIX(nameLength)(const ENCODING *enc, const char *ptr) { const char *start = ptr; for (;;) { switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: ptr += n; break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE case BT_NONASCII: case BT_NMSTRT: -#ifdef XML_NS +# ifdef XML_NS case BT_COLON: -#endif +# endif case BT_HEX: case BT_DIGIT: case BT_NAME: @@ -1702,9 +1745,8 @@ PREFIX(nameLength)(const ENCODING *enc, const char *ptr) } } -static const char * PTRFASTCALL -PREFIX(skipS)(const ENCODING *enc, const char *ptr) -{ +static const char *PTRFASTCALL +PREFIX(skipS)(const ENCODING *enc, const char *ptr) { for (;;) { switch (BYTE_TYPE(enc, ptr)) { case BT_LF: @@ -1719,19 +1761,18 @@ PREFIX(skipS)(const ENCODING *enc, const char *ptr) } static void PTRCALL -PREFIX(updatePosition)(const ENCODING *enc, - const char *ptr, - const char *end, - POSITION *pos) -{ +PREFIX(updatePosition)(const ENCODING *enc, const char *ptr, const char *end, + POSITION *pos) { while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE case BT_LF: pos->columnNumber = (XML_Size)-1; pos->lineNumber++; @@ -1752,12 +1793,12 @@ PREFIX(updatePosition)(const ENCODING *enc, } } -#undef DO_LEAD_CASE -#undef MULTIBYTE_CASES -#undef INVALID_CASES -#undef CHECK_NAME_CASE -#undef CHECK_NAME_CASES -#undef CHECK_NMSTRT_CASE -#undef CHECK_NMSTRT_CASES +# undef DO_LEAD_CASE +# undef MULTIBYTE_CASES +# undef INVALID_CASES +# undef CHECK_NAME_CASE +# undef CHECK_NAME_CASES +# undef CHECK_NMSTRT_CASE +# undef CHECK_NMSTRT_CASES #endif /* XML_TOK_IMPL_C */ diff --git a/Modules/expat/xmltok_impl.h b/Modules/expat/xmltok_impl.h index a6420f48eedc04..e925dbc7e2c833 100644 --- a/Modules/expat/xmltok_impl.h +++ b/Modules/expat/xmltok_impl.h @@ -31,43 +31,43 @@ */ enum { - BT_NONXML, - BT_MALFORM, - BT_LT, - BT_AMP, - BT_RSQB, - BT_LEAD2, - BT_LEAD3, - BT_LEAD4, - BT_TRAIL, - BT_CR, - BT_LF, - BT_GT, - BT_QUOT, - BT_APOS, - BT_EQUALS, - BT_QUEST, - BT_EXCL, - BT_SOL, - BT_SEMI, - BT_NUM, - BT_LSQB, - BT_S, - BT_NMSTRT, - BT_COLON, - BT_HEX, - BT_DIGIT, - BT_NAME, - BT_MINUS, - BT_OTHER, /* known not to be a name or name start character */ + BT_NONXML, /* e.g. noncharacter-FFFF */ + BT_MALFORM, /* illegal, with regard to encoding */ + BT_LT, /* less than = "<" */ + BT_AMP, /* ampersand = "&" */ + BT_RSQB, /* right square bracket = "[" */ + BT_LEAD2, /* lead byte of a 2-byte UTF-8 character */ + BT_LEAD3, /* lead byte of a 3-byte UTF-8 character */ + BT_LEAD4, /* lead byte of a 4-byte UTF-8 character */ + BT_TRAIL, /* trailing unit, e.g. second 16-bit unit of a 4-byte char. */ + BT_CR, /* carriage return = "\r" */ + BT_LF, /* line feed = "\n" */ + BT_GT, /* greater than = ">" */ + BT_QUOT, /* quotation character = "\"" */ + BT_APOS, /* aposthrophe = "'" */ + BT_EQUALS, /* equal sign = "=" */ + BT_QUEST, /* question mark = "?" */ + BT_EXCL, /* exclamation mark = "!" */ + BT_SOL, /* solidus, slash = "/" */ + BT_SEMI, /* semicolon = ";" */ + BT_NUM, /* number sign = "#" */ + BT_LSQB, /* left square bracket = "[" */ + BT_S, /* white space, e.g. "\t", " "[, "\r"] */ + BT_NMSTRT, /* non-hex name start letter = "G".."Z" + "g".."z" + "_" */ + BT_COLON, /* colon = ":" */ + BT_HEX, /* hex letter = "A".."F" + "a".."f" */ + BT_DIGIT, /* digit = "0".."9" */ + BT_NAME, /* dot and middle dot = "." + chr(0xb7) */ + BT_MINUS, /* minus = "-" */ + BT_OTHER, /* known not to be a name or name start character */ BT_NONASCII, /* might be a name or name start character */ - BT_PERCNT, - BT_LPAR, - BT_RPAR, - BT_AST, - BT_PLUS, - BT_COMMA, - BT_VERBAR + BT_PERCNT, /* percent sign = "%" */ + BT_LPAR, /* left parenthesis = "(" */ + BT_RPAR, /* right parenthesis = "(" */ + BT_AST, /* asterisk = "*" */ + BT_PLUS, /* plus sign = "+" */ + BT_COMMA, /* comma = "," */ + BT_VERBAR /* vertical bar = "|" */ }; #include diff --git a/Modules/expat/xmltok_ns.c b/Modules/expat/xmltok_ns.c index 23d31e8e424916..919c74e9f97fe8 100644 --- a/Modules/expat/xmltok_ns.c +++ b/Modules/expat/xmltok_ns.c @@ -33,56 +33,47 @@ #ifdef XML_TOK_NS_C const ENCODING * -NS(XmlGetUtf8InternalEncoding)(void) -{ +NS(XmlGetUtf8InternalEncoding)(void) { return &ns(internal_utf8_encoding).enc; } const ENCODING * -NS(XmlGetUtf16InternalEncoding)(void) -{ -#if BYTEORDER == 1234 +NS(XmlGetUtf16InternalEncoding)(void) { +# if BYTEORDER == 1234 return &ns(internal_little2_encoding).enc; -#elif BYTEORDER == 4321 +# elif BYTEORDER == 4321 return &ns(internal_big2_encoding).enc; -#else +# else const short n = 1; - return (*(const char *)&n - ? &ns(internal_little2_encoding).enc - : &ns(internal_big2_encoding).enc); -#endif + return (*(const char *)&n ? &ns(internal_little2_encoding).enc + : &ns(internal_big2_encoding).enc); +# endif } -static const ENCODING * const NS(encodings)[] = { - &ns(latin1_encoding).enc, - &ns(ascii_encoding).enc, - &ns(utf8_encoding).enc, - &ns(big2_encoding).enc, - &ns(big2_encoding).enc, - &ns(little2_encoding).enc, - &ns(utf8_encoding).enc /* NO_ENC */ +static const ENCODING *const NS(encodings)[] = { + &ns(latin1_encoding).enc, &ns(ascii_encoding).enc, + &ns(utf8_encoding).enc, &ns(big2_encoding).enc, + &ns(big2_encoding).enc, &ns(little2_encoding).enc, + &ns(utf8_encoding).enc /* NO_ENC */ }; static int PTRCALL NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - return initScan(NS(encodings), (const INIT_ENCODING *)enc, - XML_PROLOG_STATE, ptr, end, nextTokPtr); + const char **nextTokPtr) { + return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, + ptr, end, nextTokPtr); } static int PTRCALL NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - return initScan(NS(encodings), (const INIT_ENCODING *)enc, - XML_CONTENT_STATE, ptr, end, nextTokPtr); + const char **nextTokPtr) { + return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, + ptr, end, nextTokPtr); } int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, - const char *name) -{ + const char *name) { int i = getEncodingIndex(name); if (i == UNKNOWN_ENC) return 0; @@ -96,9 +87,8 @@ 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 +NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) { +# define ENCODING_MAX 128 char buf[ENCODING_MAX]; char *p = buf; int i; @@ -115,28 +105,14 @@ NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) } int -NS(XmlParseXmlDecl)(int isGeneralTextEntity, - const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr, - const char **versionPtr, - const char **versionEndPtr, - const char **encodingName, - const ENCODING **encoding, - int *standalone) -{ - return doParseXmlDecl(NS(findEncoding), - isGeneralTextEntity, - enc, - ptr, - end, - badPtr, - versionPtr, - versionEndPtr, - encodingName, - encoding, - standalone); +NS(XmlParseXmlDecl)(int isGeneralTextEntity, const ENCODING *enc, + const char *ptr, const char *end, const char **badPtr, + const char **versionPtr, const char **versionEndPtr, + const char **encodingName, const ENCODING **encoding, + int *standalone) { + return doParseXmlDecl(NS(findEncoding), isGeneralTextEntity, enc, ptr, end, + badPtr, versionPtr, versionEndPtr, encodingName, + encoding, standalone); } #endif /* XML_TOK_NS_C */ diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index f2b5a503f4ee1e..7b325996b268b1 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -1325,7 +1325,11 @@ _PyFaulthandler_Init(int enable) * be able to allocate memory on the stack, even on a stack overflow. If it * fails, ignore the error. */ stack.ss_flags = 0; - stack.ss_size = SIGSTKSZ; + /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just + SIGSTKSZ bytes. Calling the previous signal handler in faulthandler + signal handler uses more than SIGSTKSZ bytes of stack memory on some + platforms. */ + stack.ss_size = SIGSTKSZ * 2; stack.ss_sp = PyMem_Malloc(stack.ss_size); if (stack.ss_sp != NULL) { err = sigaltstack(&stack, &old_stack); diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 0cf00e839661f0..5a6a81d81364d7 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -373,9 +373,10 @@ update_refs(PyGC_Head *containers) /* A traversal callback for subtract_refs. */ static int -visit_decref(PyObject *op, void *data) +visit_decref(PyObject *op, void *parent) { - assert(op != NULL); + _PyObject_ASSERT(_PyObject_CAST(parent), !_PyObject_IsFreed(op)); + if (PyObject_IS_GC(op)) { PyGC_Head *gc = AS_GC(op); /* We're only interested in gc_refs for objects in the @@ -400,10 +401,11 @@ subtract_refs(PyGC_Head *containers) traverseproc traverse; PyGC_Head *gc = GC_NEXT(containers); for (; gc != containers; gc = GC_NEXT(gc)) { - traverse = Py_TYPE(FROM_GC(gc))->tp_traverse; + PyObject *op = FROM_GC(gc); + traverse = Py_TYPE(op)->tp_traverse; (void) traverse(FROM_GC(gc), (visitproc)visit_decref, - NULL); + op); } } @@ -676,6 +678,21 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) op = FROM_GC(gc); next = GC_NEXT(gc); + if (PyWeakref_Check(op)) { + /* A weakref inside the unreachable set must be cleared. If we + * allow its callback to execute inside delete_garbage(), it + * could expose objects that have tp_clear already called on + * them. Or, it could resurrect unreachable objects. One way + * this can happen is if some container objects do not implement + * tp_traverse. Then, wr_object can be outside the unreachable + * set but can be deallocated as a result of breaking the + * reference cycle. If we don't clear the weakref, the callback + * will run and potentially cause a crash. See bpo-38006 for + * one example. + */ + _PyWeakref_ClearRef((PyWeakReference *)op); + } + if (! PyType_SUPPORTS_WEAKREFS(Py_TYPE(op))) continue; @@ -731,6 +748,8 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) * is moved to wrcb_to_call in this case. */ if (gc_is_collecting(AS_GC(wr))) { + /* it should already have been cleared above */ + assert(wr->wr_object == Py_None); continue; } @@ -962,6 +981,25 @@ clear_freelists(void) (void)PyContext_ClearFreeList(); } +// Show stats for objects in each gennerations. +static void +show_stats_each_generations(struct _gc_runtime_state *state) +{ + char buf[100]; + size_t pos = 0; + + for (int i = 0; i < NUM_GENERATIONS && pos < sizeof(buf); i++) { + pos += PyOS_snprintf(buf+pos, sizeof(buf)-pos, + " %"PY_FORMAT_SIZE_T"d", + gc_list_size(GEN_HEAD(state, i))); + } + + PySys_FormatStderr( + "gc: objects in each generation:%s\n" + "gc: objects in permanent generation: %zd\n", + buf, gc_list_size(&state->permanent_generation.head)); +} + /* This is the main function. Read this to understand how the * collection process works. */ static Py_ssize_t @@ -979,17 +1017,9 @@ collect(struct _gc_runtime_state *state, int generation, _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ if (state->debug & DEBUG_STATS) { - PySys_WriteStderr("gc: collecting generation %d...\n", - generation); - PySys_WriteStderr("gc: objects in each generation:"); - for (i = 0; i < NUM_GENERATIONS; i++) - PySys_FormatStderr(" %zd", - gc_list_size(GEN_HEAD(state, i))); - PySys_WriteStderr("\ngc: objects in permanent generation: %zd", - gc_list_size(&state->permanent_generation.head)); + PySys_WriteStderr("gc: collecting generation %d...\n", generation); + show_stats_each_generations(state); t1 = _PyTime_GetMonotonicClock(); - - PySys_WriteStderr("\n"); } if (PyDTrace_GC_START_ENABLED()) @@ -1065,12 +1095,9 @@ collect(struct _gc_runtime_state *state, int generation, validate_list(&finalizers, 0); validate_list(&unreachable, PREV_MASK_COLLECTING); - /* Collect statistics on collectable objects found and print - * debugging information. - */ - for (gc = GC_NEXT(&unreachable); gc != &unreachable; gc = GC_NEXT(gc)) { - m++; - if (state->debug & DEBUG_COLLECTABLE) { + /* Print debugging information. */ + if (state->debug & DEBUG_COLLECTABLE) { + for (gc = GC_NEXT(&unreachable); gc != &unreachable; gc = GC_NEXT(gc)) { debug_cycle("collectable", FROM_GC(gc)); } } @@ -1092,6 +1119,7 @@ collect(struct _gc_runtime_state *state, int generation, * the reference cycles to be broken. It may also cause some objects * in finalizers to be freed. */ + m += gc_list_size(&unreachable); delete_garbage(state, &unreachable, old); } @@ -1103,16 +1131,11 @@ collect(struct _gc_runtime_state *state, int generation, debug_cycle("uncollectable", FROM_GC(gc)); } if (state->debug & DEBUG_STATS) { - _PyTime_t t2 = _PyTime_GetMonotonicClock(); - - if (m == 0 && n == 0) - PySys_WriteStderr("gc: done"); - else - PySys_FormatStderr( - "gc: done, %zd unreachable, %zd uncollectable", - n+m, n); - PySys_WriteStderr(", %.4fs elapsed\n", - _PyTime_AsSecondsDouble(t2 - t1)); + double d = _PyTime_AsSecondsDouble(_PyTime_GetMonotonicClock() - t1); + PySys_WriteStderr( + "gc: done, %" PY_FORMAT_SIZE_T "d unreachable, " + "%" PY_FORMAT_SIZE_T "d uncollectable, %.4fs elapsed\n", + n+m, n, d); } /* Append instances in the uncollectable set to a Python diff --git a/Modules/getpath.c b/Modules/getpath.c index 5f807381880283..b727f66953b460 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -123,16 +123,17 @@ extern "C" { typedef struct { wchar_t *path_env; /* PATH environment variable */ - wchar_t *pythonpath; /* PYTHONPATH define */ - wchar_t *prefix; /* PREFIX define */ - wchar_t *exec_prefix; /* EXEC_PREFIX define */ + wchar_t *pythonpath; /* PYTHONPATH macro */ + wchar_t *prefix; /* PREFIX macro */ + wchar_t *exec_prefix; /* EXEC_PREFIX macro */ wchar_t *lib_python; /* "lib/pythonX.Y" */ - wchar_t argv0_path[MAXPATHLEN+1]; - wchar_t zip_path[MAXPATHLEN+1]; /* ".../lib/pythonXY.zip" */ int prefix_found; /* found platform independent libraries? */ int exec_prefix_found; /* found the platform dependent libraries? */ + + int warnings; + const wchar_t *pythonpath_env; } PyCalculatePath; static const wchar_t delimiter[2] = {DELIM, '\0'}; @@ -365,17 +366,20 @@ add_exe_suffix(wchar_t *progpath, size_t progpathlen) bytes long. */ static PyStatus -search_for_prefix(const PyConfig *config, PyCalculatePath *calculate, - wchar_t *prefix, size_t prefix_len, - int *found) +search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, + const wchar_t *argv0_path, + wchar_t *prefix, size_t prefix_len, int *found) { + wchar_t path[MAXPATHLEN+1]; + memset(path, 0, sizeof(path)); + size_t path_len = Py_ARRAY_LENGTH(path); + PyStatus status; - size_t n; - wchar_t *vpath; /* If PYTHONHOME is set, we believe it unconditionally */ - if (config->home) { - if (safe_wcscpy(prefix, config->home, prefix_len) < 0) { + if (pathconfig->home) { + /* Path: / */ + if (safe_wcscpy(prefix, pathconfig->home, prefix_len) < 0) { return PATHLEN_ERR(); } wchar_t *delim = wcschr(prefix, DELIM); @@ -386,28 +390,26 @@ search_for_prefix(const PyConfig *config, PyCalculatePath *calculate, if (_PyStatus_EXCEPTION(status)) { return status; } - status = joinpath(prefix, LANDMARK, prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } *found = 1; return _PyStatus_OK(); } /* Check to see if argv[0] is in the build directory */ - if (safe_wcscpy(prefix, calculate->argv0_path, prefix_len) < 0) { + if (safe_wcscpy(path, argv0_path, path_len) < 0) { return PATHLEN_ERR(); } - status = joinpath(prefix, L"Modules/Setup.local", prefix_len); + status = joinpath(path, L"Modules/Setup.local", path_len); if (_PyStatus_EXCEPTION(status)) { return status; } - if (isfile(prefix)) { - /* Check VPATH to see if argv0_path is in the build directory. */ - vpath = Py_DecodeLocale(VPATH, NULL); + if (isfile(path)) { + /* Check VPATH to see if argv0_path is in the build directory. + VPATH can be empty. */ + wchar_t *vpath = Py_DecodeLocale(VPATH, NULL); if (vpath != NULL) { - if (safe_wcscpy(prefix, calculate->argv0_path, prefix_len) < 0) { + /* Path: / / Lib / LANDMARK */ + if (safe_wcscpy(prefix, argv0_path, prefix_len) < 0) { return PATHLEN_ERR(); } status = joinpath(prefix, vpath, prefix_len); @@ -427,19 +429,21 @@ search_for_prefix(const PyConfig *config, PyCalculatePath *calculate, if (ismodule(prefix, prefix_len)) { *found = -1; + reduce(prefix); return _PyStatus_OK(); } } } /* Search from argv0_path, until root is found */ - status = copy_absolute(prefix, calculate->argv0_path, prefix_len); + status = copy_absolute(prefix, argv0_path, prefix_len); if (_PyStatus_EXCEPTION(status)) { return status; } do { - n = wcslen(prefix); + /* Path: / / LANDMARK */ + size_t n = wcslen(prefix); status = joinpath(prefix, calculate->lib_python, prefix_len); if (_PyStatus_EXCEPTION(status)) { return status; @@ -451,13 +455,15 @@ search_for_prefix(const PyConfig *config, PyCalculatePath *calculate, if (ismodule(prefix, prefix_len)) { *found = 1; + reduce(prefix); return _PyStatus_OK(); } prefix[n] = L'\0'; reduce(prefix); } while (prefix[0]); - /* Look at configure's PREFIX */ + /* Look at configure's PREFIX. + Path: / / LANDMARK */ if (safe_wcscpy(prefix, calculate->prefix, prefix_len) < 0) { return PATHLEN_ERR(); } @@ -472,6 +478,7 @@ search_for_prefix(const PyConfig *config, PyCalculatePath *calculate, if (ismodule(prefix, prefix_len)) { *found = 1; + reduce(prefix); return _PyStatus_OK(); } @@ -482,19 +489,21 @@ search_for_prefix(const PyConfig *config, PyCalculatePath *calculate, static PyStatus -calculate_prefix(const PyConfig *config, - PyCalculatePath *calculate, wchar_t *prefix, size_t prefix_len) +calculate_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, + const wchar_t *argv0_path, + wchar_t *prefix, size_t prefix_len) { PyStatus status; - status = search_for_prefix(config, calculate, prefix, prefix_len, - &calculate->prefix_found); + status = search_for_prefix(calculate, pathconfig, argv0_path, + prefix, prefix_len, + &calculate->prefix_found); if (_PyStatus_EXCEPTION(status)) { return status; } if (!calculate->prefix_found) { - if (config->pathconfig_warnings) { + if (calculate->warnings) { fprintf(stderr, "Could not find platform independent libraries \n"); } @@ -506,16 +515,13 @@ calculate_prefix(const PyConfig *config, return status; } } - else { - reduce(prefix); - } return _PyStatus_OK(); } static PyStatus -calculate_reduce_prefix(PyCalculatePath *calculate, - wchar_t *prefix, size_t prefix_len) +calculate_set_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, + wchar_t *prefix) { /* Reduce prefix and exec_prefix to their essence, * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. @@ -530,38 +536,102 @@ calculate_reduce_prefix(PyCalculatePath *calculate, if (!prefix[0]) { wcscpy(prefix, separator); } + pathconfig->prefix = _PyMem_RawWcsdup(prefix); } else { - if (safe_wcscpy(prefix, calculate->prefix, prefix_len) < 0) { - return PATHLEN_ERR(); - } + pathconfig->prefix = _PyMem_RawWcsdup(calculate->prefix); + } + + 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; + + wchar_t filename[MAXPATHLEN+1]; + memset(filename, 0, sizeof(filename)); + size_t filename_len = Py_ARRAY_LENGTH(filename); + + /* 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" */ + if (safe_wcscpy(filename, argv0_path, filename_len) < 0) { + return PATHLEN_ERR(); + } + status = joinpath(filename, L"pybuilddir.txt", filename_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (!isfile(filename)) { + return _PyStatus_OK(); + } + + FILE *fp = _Py_wfopen(filename, L"rb"); + 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'; + 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); + } + + /* 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(const PyConfig *config, - PyCalculatePath *calculate, +search_for_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, + const wchar_t *argv0_path, wchar_t *exec_prefix, size_t exec_prefix_len, int *found) { PyStatus status; - size_t n; /* If PYTHONHOME is set, we believe it unconditionally */ - if (config->home) { - wchar_t *delim = wcschr(config->home, DELIM); + 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, config->home, exec_prefix_len) < 0) { + if (safe_wcscpy(exec_prefix, pathconfig->home, exec_prefix_len) < 0) { return PATHLEN_ERR(); } } @@ -577,57 +647,26 @@ search_for_exec_prefix(const PyConfig *config, return _PyStatus_OK(); } - /* 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. */ - if (safe_wcscpy(exec_prefix, calculate->argv0_path, exec_prefix_len) < 0) { - return PATHLEN_ERR(); - } - status = joinpath(exec_prefix, L"pybuilddir.txt", exec_prefix_len); + /* Check for pybuilddir.txt */ + assert(*found == 0); + status = calculate_pybuilddir(argv0_path, exec_prefix, exec_prefix_len, + found); if (_PyStatus_EXCEPTION(status)) { return status; } - - if (isfile(exec_prefix)) { - FILE *f = _Py_wfopen(exec_prefix, L"rb"); - if (f == NULL) { - errno = 0; - } - else { - char buf[MAXPATHLEN + 1]; - n = fread(buf, 1, Py_ARRAY_LENGTH(buf) - 1, f); - buf[n] = '\0'; - fclose(f); - - wchar_t *pybuilddir; - size_t dec_len; - pybuilddir = _Py_DecodeUTF8_surrogateescape(buf, n, &dec_len); - if (!pybuilddir) { - return DECODE_LOCALE_ERR("pybuilddir.txt", dec_len); - } - - if (safe_wcscpy(exec_prefix, calculate->argv0_path, exec_prefix_len) < 0) { - 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(); - } + if (*found) { + return _PyStatus_OK(); } /* Search from argv0_path, until root is found */ - status = copy_absolute(exec_prefix, calculate->argv0_path, exec_prefix_len); + status = copy_absolute(exec_prefix, argv0_path, exec_prefix_len); if (_PyStatus_EXCEPTION(status)) { return status; } do { - n = wcslen(exec_prefix); + /* 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; @@ -644,7 +683,9 @@ search_for_exec_prefix(const PyConfig *config, reduce(exec_prefix); } while (exec_prefix[0]); - /* Look at configure's EXEC_PREFIX */ + /* Look at configure's EXEC_PREFIX. + + Path: / / "lib-dynload" */ if (safe_wcscpy(exec_prefix, calculate->exec_prefix, exec_prefix_len) < 0) { return PATHLEN_ERR(); } @@ -668,21 +709,21 @@ search_for_exec_prefix(const PyConfig *config, static PyStatus -calculate_exec_prefix(const PyConfig *config, - PyCalculatePath *calculate, +calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, + const wchar_t *argv0_path, wchar_t *exec_prefix, size_t exec_prefix_len) { PyStatus status; - status = search_for_exec_prefix(config, calculate, - exec_prefix, exec_prefix_len, - &calculate->exec_prefix_found); + status = search_for_exec_prefix(calculate, pathconfig, argv0_path, + exec_prefix, exec_prefix_len, + &calculate->exec_prefix_found); if (_PyStatus_EXCEPTION(status)) { return status; } if (!calculate->exec_prefix_found) { - if (config->pathconfig_warnings) { + if (calculate->warnings) { fprintf(stderr, "Could not find platform dependent libraries \n"); } @@ -700,8 +741,9 @@ calculate_exec_prefix(const PyConfig *config, static PyStatus -calculate_reduce_exec_prefix(PyCalculatePath *calculate, - wchar_t *exec_prefix, size_t exec_prefix_len) +calculate_set_exec_prefix(PyCalculatePath *calculate, + _PyPathConfig *pathconfig, + wchar_t *exec_prefix) { if (calculate->exec_prefix_found > 0) { reduce(exec_prefix); @@ -710,19 +752,23 @@ calculate_reduce_exec_prefix(PyCalculatePath *calculate, if (!exec_prefix[0]) { wcscpy(exec_prefix, separator); } + + pathconfig->exec_prefix = _PyMem_RawWcsdup(exec_prefix); } else { - if (safe_wcscpy(exec_prefix, calculate->exec_prefix, exec_prefix_len) < 0) { - return PATHLEN_ERR(); - } + pathconfig->exec_prefix = _PyMem_RawWcsdup(calculate->exec_prefix); + } + + if (pathconfig->exec_prefix == NULL) { + return _PyStatus_NO_MEMORY(); } + return _PyStatus_OK(); } static PyStatus -calculate_program_full_path(const PyConfig *config, - PyCalculatePath *calculate, _PyPathConfig *pathconfig) +calculate_program_full_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) { PyStatus status; wchar_t program_full_path[MAXPATHLEN + 1]; @@ -743,8 +789,8 @@ calculate_program_full_path(const PyConfig *config, * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ - if (wcschr(config->program_name, SEP)) { - if (safe_wcscpy(program_full_path, config->program_name, + if (wcschr(pathconfig->program_name, SEP)) { + if (safe_wcscpy(program_full_path, pathconfig->program_name, program_full_path_len) < 0) { return PATHLEN_ERR(); } @@ -795,8 +841,8 @@ calculate_program_full_path(const PyConfig *config, } } - status = joinpath(program_full_path, config->program_name, - program_full_path_len); + status = joinpath(program_full_path, pathconfig->program_name, + program_full_path_len); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -844,10 +890,10 @@ calculate_program_full_path(const PyConfig *config, static PyStatus -calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_path) +calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_path, + wchar_t *argv0_path, size_t argv0_path_len) { - const size_t argv0_path_len = Py_ARRAY_LENGTH(calculate->argv0_path); - if (safe_wcscpy(calculate->argv0_path, program_full_path, argv0_path_len) < 0) { + if (safe_wcscpy(argv0_path, program_full_path, argv0_path_len) < 0) { return PATHLEN_ERR(); } @@ -878,32 +924,31 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat return DECODE_LOCALE_ERR("framework location", len); } - if (safe_wcscpy(calculate->argv0_path, wbuf, argv0_path_len) < 0) { + if (safe_wcscpy(argv0_path, wbuf, argv0_path_len) < 0) { return PATHLEN_ERR(); } - reduce(calculate->argv0_path); - status = joinpath(calculate->argv0_path, calculate->lib_python, argv0_path_len); + reduce(argv0_path); + status = joinpath(argv0_path, calculate->lib_python, argv0_path_len); if (_PyStatus_EXCEPTION(status)) { PyMem_RawFree(wbuf); return status; } - status = joinpath(calculate->argv0_path, LANDMARK, argv0_path_len); + status = joinpath(argv0_path, LANDMARK, argv0_path_len); if (_PyStatus_EXCEPTION(status)) { PyMem_RawFree(wbuf); return status; } - if (!ismodule(calculate->argv0_path, - Py_ARRAY_LENGTH(calculate->argv0_path))) { + if (!ismodule(argv0_path, Py_ARRAY_LENGTH(argv0_path))) { /* We are in the build directory so use the name of the executable - we know that the absolute path is passed */ - if (safe_wcscpy(calculate->argv0_path, program_full_path, + if (safe_wcscpy(argv0_path, program_full_path, argv0_path_len) < 0) { return PATHLEN_ERR(); } } else { /* Use the location of the library as the program_full_path */ - if (safe_wcscpy(calculate->argv0_path, wbuf, argv0_path_len) < 0) { + if (safe_wcscpy(argv0_path, wbuf, argv0_path_len) < 0) { return PATHLEN_ERR(); } } @@ -919,24 +964,24 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat if (tmpbuffer[0] == SEP) { /* tmpbuffer should never be longer than MAXPATHLEN, but extra check does not hurt */ - if (safe_wcscpy(calculate->argv0_path, tmpbuffer, argv0_path_len) < 0) { + if (safe_wcscpy(argv0_path, tmpbuffer, argv0_path_len) < 0) { return PATHLEN_ERR(); } } else { /* Interpret relative to program_full_path */ PyStatus status; - reduce(calculate->argv0_path); - status = joinpath(calculate->argv0_path, tmpbuffer, argv0_path_len); + reduce(argv0_path); + status = joinpath(argv0_path, tmpbuffer, argv0_path_len); if (_PyStatus_EXCEPTION(status)) { return status; } } - linklen = _Py_wreadlink(calculate->argv0_path, tmpbuffer, buflen); + linklen = _Py_wreadlink(argv0_path, tmpbuffer, buflen); } #endif /* HAVE_READLINK */ - reduce(calculate->argv0_path); + reduce(argv0_path); /* At this point, argv0_path is guaranteed to be less than MAXPATHLEN bytes long. */ return _PyStatus_OK(); @@ -948,47 +993,53 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat If found, open it for use when searching for prefixes. */ static PyStatus -calculate_read_pyenv(PyCalculatePath *calculate) +calculate_read_pyenv(PyCalculatePath *calculate, + wchar_t *argv0_path, size_t argv0_path_len) { PyStatus status; - wchar_t tmpbuffer[MAXPATHLEN+1]; - const size_t buflen = Py_ARRAY_LENGTH(tmpbuffer); - wchar_t *env_cfg = L"pyvenv.cfg"; + const wchar_t *env_cfg = L"pyvenv.cfg"; FILE *env_file; - if (safe_wcscpy(tmpbuffer, calculate->argv0_path, buflen) < 0) { + wchar_t filename[MAXPATHLEN+1]; + const size_t filename_len = Py_ARRAY_LENGTH(filename); + memset(filename, 0, sizeof(filename)); + + /* Filename: / "pyvenv.cfg" */ + if (safe_wcscpy(filename, argv0_path, filename_len) < 0) { return PATHLEN_ERR(); } - status = joinpath(tmpbuffer, env_cfg, buflen); + status = joinpath(filename, env_cfg, filename_len); if (_PyStatus_EXCEPTION(status)) { return status; } - env_file = _Py_wfopen(tmpbuffer, L"r"); + env_file = _Py_wfopen(filename, L"r"); if (env_file == NULL) { errno = 0; - reduce(tmpbuffer); - reduce(tmpbuffer); - status = joinpath(tmpbuffer, env_cfg, buflen); + /* Filename: / "pyvenv.cfg" */ + reduce(filename); + reduce(filename); + status = joinpath(filename, env_cfg, filename_len); if (_PyStatus_EXCEPTION(status)) { return status; } - env_file = _Py_wfopen(tmpbuffer, L"r"); + env_file = _Py_wfopen(filename, L"r"); if (env_file == NULL) { errno = 0; + return _PyStatus_OK(); } } - if (env_file == NULL) { - return _PyStatus_OK(); - } - /* Look for a 'home' variable and set argv0_path to it, if found */ - if (_Py_FindEnvConfigValue(env_file, L"home", tmpbuffer, buflen)) { - if (safe_wcscpy(calculate->argv0_path, tmpbuffer, - Py_ARRAY_LENGTH(calculate->argv0_path)) < 0) { + wchar_t home[MAXPATHLEN+1]; + memset(home, 0, sizeof(home)); + + if (_Py_FindEnvConfigValue(env_file, L"home", + home, Py_ARRAY_LENGTH(home))) { + if (safe_wcscpy(argv0_path, home, argv0_path_len) < 0) { + fclose(env_file); return PATHLEN_ERR(); } } @@ -998,47 +1049,48 @@ calculate_read_pyenv(PyCalculatePath *calculate) static PyStatus -calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix) +calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix, + wchar_t *zip_path, size_t zip_path_len) { PyStatus status; - const size_t zip_path_len = Py_ARRAY_LENGTH(calculate->zip_path); - if (safe_wcscpy(calculate->zip_path, prefix, zip_path_len) < 0) { - return PATHLEN_ERR(); - } if (calculate->prefix_found > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */ - reduce(calculate->zip_path); - reduce(calculate->zip_path); + if (safe_wcscpy(zip_path, prefix, zip_path_len) < 0) { + return PATHLEN_ERR(); + } + reduce(zip_path); + reduce(zip_path); } else { - if (safe_wcscpy(calculate->zip_path, calculate->prefix, zip_path_len) < 0) { + if (safe_wcscpy(zip_path, calculate->prefix, zip_path_len) < 0) { return PATHLEN_ERR(); } } - status = joinpath(calculate->zip_path, L"lib/python00.zip", zip_path_len); + status = joinpath(zip_path, L"lib/python00.zip", zip_path_len); if (_PyStatus_EXCEPTION(status)) { return status; } /* Replace "00" with version */ - size_t bufsz = wcslen(calculate->zip_path); - calculate->zip_path[bufsz - 6] = VERSION[0]; - calculate->zip_path[bufsz - 5] = VERSION[2]; + size_t bufsz = wcslen(zip_path); + zip_path[bufsz - 6] = VERSION[0]; + zip_path[bufsz - 5] = VERSION[2]; return _PyStatus_OK(); } static PyStatus -calculate_module_search_path(const PyConfig *config, - PyCalculatePath *calculate, - const wchar_t *prefix, const wchar_t *exec_prefix, - _PyPathConfig *pathconfig) +calculate_module_search_path(PyCalculatePath *calculate, + _PyPathConfig *pathconfig, + const wchar_t *prefix, + const wchar_t *exec_prefix, + const wchar_t *zip_path) { /* Calculate size of return buffer */ size_t bufsz = 0; - if (config->pythonpath_env != NULL) { - bufsz += wcslen(config->pythonpath_env) + 1; + if (calculate->pythonpath_env != NULL) { + bufsz += wcslen(calculate->pythonpath_env) + 1; } wchar_t *defpath = calculate->pythonpath; @@ -1061,7 +1113,7 @@ calculate_module_search_path(const PyConfig *config, defpath = delim + 1; } - bufsz += wcslen(calculate->zip_path) + 1; + bufsz += wcslen(zip_path) + 1; bufsz += wcslen(exec_prefix) + 1; /* Allocate the buffer */ @@ -1072,13 +1124,13 @@ calculate_module_search_path(const PyConfig *config, buf[0] = '\0'; /* Run-time value of $PYTHONPATH goes first */ - if (config->pythonpath_env) { - wcscpy(buf, config->pythonpath_env); + if (calculate->pythonpath_env) { + wcscpy(buf, calculate->pythonpath_env); wcscat(buf, delimiter); } /* Next is the default zip path */ - wcscat(buf, calculate->zip_path); + wcscat(buf, zip_path); wcscat(buf, delimiter); /* Next goes merge of compile-time $PYTHONPATH with @@ -1121,8 +1173,7 @@ calculate_module_search_path(const PyConfig *config, static PyStatus -calculate_init(PyCalculatePath *calculate, - const PyConfig *config) +calculate_init(PyCalculatePath *calculate, const PyConfig *config) { size_t len; const char *path = getenv("PATH"); @@ -1137,18 +1188,23 @@ calculate_init(PyCalculatePath *calculate, if (!calculate->pythonpath) { return DECODE_LOCALE_ERR("PYTHONPATH define", len); } + calculate->prefix = Py_DecodeLocale(PREFIX, &len); if (!calculate->prefix) { return DECODE_LOCALE_ERR("PREFIX define", len); } calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len); - if (!calculate->prefix) { + if (!calculate->exec_prefix) { return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); } calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len); if (!calculate->lib_python) { return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); } + + calculate->warnings = config->pathconfig_warnings; + calculate->pythonpath_env = config->pythonpath_env; + return _PyStatus_OK(); } @@ -1165,85 +1221,123 @@ calculate_free(PyCalculatePath *calculate) static PyStatus -calculate_path_impl(const PyConfig *config, - PyCalculatePath *calculate, _PyPathConfig *pathconfig) +calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) { PyStatus status; - status = calculate_program_full_path(config, calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; + if (pathconfig->program_full_path == NULL) { + status = calculate_program_full_path(calculate, pathconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; + } } - status = calculate_argv0_path(calculate, pathconfig->program_full_path); + wchar_t argv0_path[MAXPATHLEN+1]; + memset(argv0_path, 0, sizeof(argv0_path)); + + status = calculate_argv0_path(calculate, pathconfig->program_full_path, + argv0_path, Py_ARRAY_LENGTH(argv0_path)); if (_PyStatus_EXCEPTION(status)) { return status; } - status = calculate_read_pyenv(calculate); + /* If a pyvenv.cfg configure file is found, + argv0_path is overriden with its 'home' variable. */ + status = calculate_read_pyenv(calculate, + argv0_path, Py_ARRAY_LENGTH(argv0_path)); if (_PyStatus_EXCEPTION(status)) { return status; } wchar_t prefix[MAXPATHLEN+1]; memset(prefix, 0, sizeof(prefix)); - status = calculate_prefix(config, calculate, - prefix, Py_ARRAY_LENGTH(prefix)); + status = calculate_prefix(calculate, pathconfig, + argv0_path, + prefix, Py_ARRAY_LENGTH(prefix)); if (_PyStatus_EXCEPTION(status)) { return status; } - status = calculate_zip_path(calculate, prefix); + wchar_t zip_path[MAXPATHLEN+1]; /* ".../lib/pythonXY.zip" */ + memset(zip_path, 0, sizeof(zip_path)); + + status = calculate_zip_path(calculate, prefix, + zip_path, Py_ARRAY_LENGTH(zip_path)); if (_PyStatus_EXCEPTION(status)) { return status; } wchar_t exec_prefix[MAXPATHLEN+1]; memset(exec_prefix, 0, sizeof(exec_prefix)); - status = calculate_exec_prefix(config, calculate, - exec_prefix, Py_ARRAY_LENGTH(exec_prefix)); + status = calculate_exec_prefix(calculate, pathconfig, argv0_path, + exec_prefix, Py_ARRAY_LENGTH(exec_prefix)); if (_PyStatus_EXCEPTION(status)) { return status; } if ((!calculate->prefix_found || !calculate->exec_prefix_found) && - config->pathconfig_warnings) + calculate->warnings) { fprintf(stderr, "Consider setting $PYTHONHOME to [:]\n"); } - status = calculate_module_search_path(config, calculate, - prefix, exec_prefix, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = calculate_reduce_prefix(calculate, prefix, Py_ARRAY_LENGTH(prefix)); - if (_PyStatus_EXCEPTION(status)) { - return status; + if (pathconfig->module_search_path == NULL) { + status = calculate_module_search_path(calculate, pathconfig, + prefix, exec_prefix, zip_path); + if (_PyStatus_EXCEPTION(status)) { + return status; + } } - pathconfig->prefix = _PyMem_RawWcsdup(prefix); if (pathconfig->prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - - status = calculate_reduce_exec_prefix(calculate, - exec_prefix, Py_ARRAY_LENGTH(exec_prefix)); - if (_PyStatus_EXCEPTION(status)) { - return status; + status = calculate_set_prefix(calculate, pathconfig, prefix); + if (_PyStatus_EXCEPTION(status)) { + return status; + } } - pathconfig->exec_prefix = _PyMem_RawWcsdup(exec_prefix); if (pathconfig->exec_prefix == NULL) { - return _PyStatus_NO_MEMORY(); + status = calculate_set_exec_prefix(calculate, pathconfig, exec_prefix); + 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) { @@ -1256,7 +1350,7 @@ _PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config) goto done; } - status = calculate_path_impl(config, &calculate, pathconfig); + status = calculate_path(&calculate, pathconfig); if (_PyStatus_EXCEPTION(status)) { goto done; } diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 00e3cbb31b53b8..eba59ba1b88034 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -443,6 +443,7 @@ typedef struct { PyObject_HEAD PyObject *it; int numread; /* 0 <= numread <= LINKCELLS */ + int running; PyObject *nextlink; PyObject *(values[LINKCELLS]); } teedataobject; @@ -465,6 +466,7 @@ teedataobject_newinternal(PyObject *it) if (tdo == NULL) return NULL; + tdo->running = 0; tdo->numread = 0; tdo->nextlink = NULL; Py_INCREF(it); @@ -493,7 +495,14 @@ teedataobject_getitem(teedataobject *tdo, int i) else { /* this is the lead iterator, so fetch more data */ assert(i == tdo->numread); + if (tdo->running) { + PyErr_SetString(PyExc_RuntimeError, + "cannot re-enter the tee iterator"); + return NULL; + } + tdo->running = 1; value = PyIter_Next(tdo->it); + tdo->running = 0; if (value == NULL) return NULL; tdo->numread++; @@ -4434,10 +4443,6 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *item = PyTuple_GET_ITEM(args, i); PyObject *it = PyObject_GetIter(item); if (it == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - PyErr_Format(PyExc_TypeError, - "zip_longest argument #%zd must support iteration", - i+1); Py_DECREF(ittuple); return NULL; } diff --git a/Modules/main.c b/Modules/main.c index 6b9406f7866672..2a360b58efa831 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -54,16 +54,14 @@ pymain_init(const _PyArgv *args) PyPreConfig preconfig; PyPreConfig_InitPythonConfig(&preconfig); + status = _Py_PreInitializeFromPyArgv(&preconfig, args); if (_PyStatus_EXCEPTION(status)) { return status; } PyConfig config; - status = PyConfig_InitPythonConfig(&config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } + PyConfig_InitPythonConfig(&config); /* pass NULL as the config: config is read from command line arguments, environment variables, configuration files */ @@ -74,14 +72,18 @@ pymain_init(const _PyArgv *args) status = PyConfig_SetArgv(&config, args->argc, args->wchar_argv); } if (_PyStatus_EXCEPTION(status)) { - return status; + goto done; } status = Py_InitializeFromConfig(&config); if (_PyStatus_EXCEPTION(status)) { - return status; + goto done; } - return _PyStatus_OK(); + status = _PyStatus_OK(); + +done: + PyConfig_Clear(&config); + return status; } @@ -243,6 +245,10 @@ pymain_run_command(wchar_t *command, PyCompilerFlags *cf) goto error; } + if (PySys_Audit("cpython.run_command", "O", unicode) < 0) { + return pymain_exit_err_print(); + } + bytes = PyUnicode_AsUTF8String(unicode); Py_DECREF(unicode); if (bytes == NULL) { @@ -263,6 +269,9 @@ static int pymain_run_module(const wchar_t *modname, int set_argv0) { PyObject *module, *runpy, *runmodule, *runargs, *result; + if (PySys_Audit("cpython.run_module", "u", modname) < 0) { + return pymain_exit_err_print(); + } runpy = PyImport_ImportModule("runpy"); if (runpy == NULL) { fprintf(stderr, "Could not import runpy module\n"); @@ -307,6 +316,9 @@ static int pymain_run_file(PyConfig *config, PyCompilerFlags *cf) { const wchar_t *filename = config->run_filename; + if (PySys_Audit("cpython.run_file", "u", filename) < 0) { + return pymain_exit_err_print(); + } FILE *fp = _Py_wfopen(filename, L"rb"); if (fp == NULL) { char *cfilename_buffer; @@ -379,6 +391,9 @@ pymain_run_startup(PyConfig *config, PyCompilerFlags *cf, int *exitcode) if (startup == NULL) { return 0; } + if (PySys_Audit("cpython.run_startup", "s", startup) < 0) { + return pymain_err_print(exitcode); + } FILE *fp = _Py_fopen(startup, "r"); if (fp == NULL) { @@ -416,6 +431,10 @@ pymain_run_interactive_hook(int *exitcode) return 0; } + if (PySys_Audit("cpython.run_interactivehook", "O", hook) < 0) { + goto error; + } + result = _PyObject_CallNoArg(hook); Py_DECREF(hook); if (result == NULL) { @@ -453,6 +472,10 @@ pymain_run_stdin(PyConfig *config, PyCompilerFlags *cf) return pymain_exit_err_print(); } + if (PySys_Audit("cpython.run_stdin", NULL) < 0) { + return pymain_exit_err_print(); + } + int run = PyRun_AnyFileExFlags(stdin, "", 0, cf); return (run != 0); } @@ -524,7 +547,7 @@ pymain_run_python(int *exitcode) } } - PyCompilerFlags cf = {.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION}; + PyCompilerFlags cf = _PyCompilerFlags_INIT; pymain_header(config); pymain_import_readline(config); diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 9a9a8159ced407..4e97337811113d 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1527,10 +1527,10 @@ Here's Python code equivalent to the C implementation below: a = 1 d = 0 for s in reversed(range(c.bit_length())): + # Loop invariant: (a-1)**2 < (n >> 2*(c - d)) < (a+1)**2 e = d d = c >> s a = (a << d - e - 1) + (n >> 2*c - e - d + 1) // a - assert (a-1)**2 < n >> 2*(c - d) < (a+1)**2 return a - (a*a > n) @@ -1552,7 +1552,7 @@ prove that after that line is executed, we have (a - 1)**2 < (n >> 2*(c - d)) < (a + 1)**2 -To faciliate the proof, we make some changes of notation. Write `m` for +To facilitate the proof, we make some changes of notation. Write `m` for `n >> 2*(c-d)`, and write `b` for the new value of `a`, so b = (a << d - e - 1) + (n >> 2*c - e - d + 1) // a @@ -2418,14 +2418,14 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) /*[clinic input] math.dist - p: object(subclass_of='&PyTuple_Type') - q: object(subclass_of='&PyTuple_Type') + p: object + q: object / Return the Euclidean distance between two points p and q. -The points should be specified as tuples of coordinates. -Both tuples must be the same size. +The points should be specified as sequences (or iterables) of +coordinates. Both inputs must have the same dimension. Roughly equivalent to: sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q))) @@ -2433,16 +2433,34 @@ Roughly equivalent to: static PyObject * math_dist_impl(PyObject *module, PyObject *p, PyObject *q) -/*[clinic end generated code: output=56bd9538d06bbcfe input=937122eaa5f19272]*/ +/*[clinic end generated code: output=56bd9538d06bbcfe input=74e85e1b6092e68e]*/ { PyObject *item; double max = 0.0; double x, px, qx, result; Py_ssize_t i, m, n; - int found_nan = 0; + int found_nan = 0, p_allocated = 0, q_allocated = 0; double diffs_on_stack[NUM_STACK_ELEMS]; double *diffs = diffs_on_stack; + if (!PyTuple_Check(p)) { + p = PySequence_Tuple(p); + if (p == NULL) { + return NULL; + } + p_allocated = 1; + } + if (!PyTuple_Check(q)) { + q = PySequence_Tuple(q); + if (q == NULL) { + if (p_allocated) { + Py_DECREF(p); + } + return NULL; + } + q_allocated = 1; + } + m = PyTuple_GET_SIZE(p); n = PyTuple_GET_SIZE(q); if (m != n) { @@ -2473,12 +2491,24 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q) if (diffs != diffs_on_stack) { PyObject_Free(diffs); } + if (p_allocated) { + Py_DECREF(p); + } + if (q_allocated) { + Py_DECREF(q); + } return PyFloat_FromDouble(result); error_exit: if (diffs != diffs_on_stack) { PyObject_Free(diffs); } + if (p_allocated) { + Py_DECREF(p); + } + if (q_allocated) { + Py_DECREF(q); + } return NULL; } @@ -3002,7 +3032,7 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) math.perm n: object - k: object + k: object = None / Number of ways to choose k items from n items without repetition and with order. @@ -3010,18 +3040,24 @@ Number of ways to choose k items from n items without repetition and with order. Evaluates to n! / (n - k)! when k <= n and evaluates to zero when k > n. +If k is not specified or is None, then k defaults to n +and the function returns n!. + Raises TypeError if either of the arguments are not integers. Raises ValueError if either of the arguments are negative. [clinic start generated code]*/ static PyObject * math_perm_impl(PyObject *module, PyObject *n, PyObject *k) -/*[clinic end generated code: output=e021a25469653e23 input=b2e7729d9a1949cf]*/ +/*[clinic end generated code: output=e021a25469653e23 input=5311c5a00f359b53]*/ { PyObject *result = NULL, *factor = NULL; int overflow, cmp; long long i, factors; + if (k == Py_None) { + return math_factorial(module, n); + } n = PyNumber_Index(n); if (n == NULL) { return NULL; @@ -3050,6 +3086,12 @@ math_perm_impl(PyObject *module, PyObject *n, PyObject *k) "n must be a non-negative integer"); goto error; } + if (Py_SIZE(k) < 0) { + PyErr_SetString(PyExc_ValueError, + "k must be a non-negative integer"); + goto error; + } + cmp = PyObject_RichCompareBool(n, k, Py_LT); if (cmp != 0) { if (cmp > 0) { @@ -3066,11 +3108,8 @@ math_perm_impl(PyObject *module, PyObject *n, PyObject *k) LLONG_MAX); goto error; } - else if (overflow < 0 || factors < 0) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ValueError, - "k must be a non-negative integer"); - } + else if (factors == -1) { + /* k is nonnegative, so a return value of -1 can only indicate error */ goto error; } @@ -3170,6 +3209,12 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) "n must be a non-negative integer"); goto error; } + if (Py_SIZE(k) < 0) { + PyErr_SetString(PyExc_ValueError, + "k must be a non-negative integer"); + goto error; + } + /* k = min(k, n - k) */ temp = PyNumber_Subtract(n, k); if (temp == NULL) { @@ -3198,11 +3243,8 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) LLONG_MAX); goto error; } - else if (overflow < 0 || factors < 0) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ValueError, - "k must be a non-negative integer"); - } + if (factors == -1) { + /* k is nonnegative, so a return value of -1 can only indicate error */ goto error; } diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 755f1669d8d321..18758861a62e9c 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1154,7 +1154,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) } if (PySys_Audit("mmap.__new__", "ini" _Py_PARSE_OFF_T, - fileno, map_size, access, offset) < 0) { + fd, map_size, access, offset) < 0) { return NULL; } @@ -1468,7 +1468,8 @@ static void setint(PyObject *d, const char *name, long value) { PyObject *o = PyLong_FromLong(value); - if (o && PyDict_SetItemString(d, name, o) == 0) { + if (o) { + PyDict_SetItemString(d, name, o); Py_DECREF(o); } } diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 44a0a5a834633f..52ed0bc284bcc0 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -500,7 +500,8 @@ overlapped_FormatMessage(PyObject *ignore, PyObject *args) return NULL; n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 36f92141915365..079d00f32aa6cd 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -336,8 +336,7 @@ parser_newstobject(node *st, int type) if (o != 0) { o->st_node = st; o->st_type = type; - o->st_flags.cf_flags = 0; - o->st_flags.cf_feature_version = PY_MINOR_VERSION; + o->st_flags = _PyCompilerFlags_INIT; } else { PyNode_Free(st); diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 8f6cffffcdfbe8..7c823434e67fe0 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -505,17 +505,6 @@ void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, ULONG, struct _Py_stat_struct *); #endif -#ifdef MS_WINDOWS -static int -win32_warn_bytes_api() -{ - return PyErr_WarnEx(PyExc_DeprecationWarning, - "The Windows bytes API has been deprecated, " - "use Unicode filenames instead", - 1); -} -#endif - #ifndef MS_WINDOWS PyObject * @@ -1635,6 +1624,7 @@ win32_wchdir(LPCWSTR path) */ #define HAVE_STAT_NSEC 1 #define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1 +#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1 static void find_data_to_file_info(WIN32_FIND_DATAW *pFileData, @@ -1668,136 +1658,185 @@ attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *re return TRUE; } -static BOOL -get_target_path(HANDLE hdl, wchar_t **target_path) -{ - int buf_size, result_length; - wchar_t *buf; - - /* We have a good handle to the target, use it to determine - the target path name (then we'll call lstat on it). */ - buf_size = GetFinalPathNameByHandleW(hdl, 0, 0, - VOLUME_NAME_DOS); - if(!buf_size) - return FALSE; - - buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t)); - if (!buf) { - SetLastError(ERROR_OUTOFMEMORY); - return FALSE; - } - - result_length = GetFinalPathNameByHandleW(hdl, - buf, buf_size, VOLUME_NAME_DOS); - - if(!result_length) { - PyMem_RawFree(buf); - return FALSE; - } - - buf[result_length] = 0; - - *target_path = buf; - return TRUE; -} - static int win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) { - int code; - HANDLE hFile, hFile2; - BY_HANDLE_FILE_INFORMATION info; - ULONG reparse_tag = 0; - wchar_t *target_path; - const wchar_t *dot; + HANDLE hFile; + BY_HANDLE_FILE_INFORMATION fileInfo; + FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 }; + DWORD fileType, error; + BOOL isUnhandledTag = FALSE; + int retval = 0; - hFile = CreateFileW( - path, - FILE_READ_ATTRIBUTES, /* desired access */ - 0, /* share mode */ - NULL, /* security attributes */ - OPEN_EXISTING, - /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ - /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. - Because of this, calls like GetFinalPathNameByHandle will return - the symlink path again and not the actual final path. */ - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| - FILE_FLAG_OPEN_REPARSE_POINT, - NULL); + DWORD access = FILE_READ_ATTRIBUTES; + DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */ + if (!traverse) { + flags |= FILE_FLAG_OPEN_REPARSE_POINT; + } + hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL); if (hFile == INVALID_HANDLE_VALUE) { - /* Either the target doesn't exist, or we don't have access to - get a handle to it. If the former, we need to return an error. - If the latter, we can use attributes_from_dir. */ - DWORD lastError = GetLastError(); - if (lastError != ERROR_ACCESS_DENIED && - lastError != ERROR_SHARING_VIOLATION) - return -1; - /* Could not get attributes on open file. Fall back to - reading the directory. */ - if (!attributes_from_dir(path, &info, &reparse_tag)) - /* Very strange. This should not fail now */ - return -1; - if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - if (traverse) { - /* Should traverse, but could not open reparse point handle */ - SetLastError(lastError); + /* Either the path doesn't exist, or the caller lacks access. */ + error = GetLastError(); + switch (error) { + case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */ + case ERROR_SHARING_VIOLATION: /* It's a paging file. */ + /* Try reading the parent directory. */ + if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) { + /* Cannot read the parent directory. */ + SetLastError(error); return -1; } - } - } else { - if (!GetFileInformationByHandle(hFile, &info)) { - CloseHandle(hFile); - return -1; - } - if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - if (!win32_get_reparse_tag(hFile, &reparse_tag)) { - CloseHandle(hFile); - return -1; + if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + if (traverse || + !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) { + /* The stat call has to traverse but cannot, so fail. */ + SetLastError(error); + return -1; + } } - /* Close the outer open file handle now that we're about to - reopen it with different flags. */ - if (!CloseHandle(hFile)) + break; + + case ERROR_INVALID_PARAMETER: + /* \\.\con requires read or write access. */ + hFile = CreateFileW(path, access | GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, flags, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + SetLastError(error); return -1; + } + break; + case ERROR_CANT_ACCESS_FILE: + /* bpo37834: open unhandled reparse points if traverse fails. */ if (traverse) { - /* In order to call GetFinalPathNameByHandle we need to open - the file without the reparse handling flag set. */ - hFile2 = CreateFileW( - path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, - NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, - NULL); - if (hFile2 == INVALID_HANDLE_VALUE) - return -1; + traverse = FALSE; + isUnhandledTag = TRUE; + hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, + flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL); + } + if (hFile == INVALID_HANDLE_VALUE) { + SetLastError(error); + return -1; + } + break; - if (!get_target_path(hFile2, &target_path)) { - CloseHandle(hFile2); - return -1; - } + default: + return -1; + } + } - if (!CloseHandle(hFile2)) { - return -1; + if (hFile != INVALID_HANDLE_VALUE) { + /* Handle types other than files on disk. */ + fileType = GetFileType(hFile); + if (fileType != FILE_TYPE_DISK) { + if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) { + retval = -1; + goto cleanup; + } + DWORD fileAttributes = GetFileAttributesW(path); + memset(result, 0, sizeof(*result)); + if (fileAttributes != INVALID_FILE_ATTRIBUTES && + fileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + /* \\.\pipe\ or \\.\mailslot\ */ + result->st_mode = _S_IFDIR; + } else if (fileType == FILE_TYPE_CHAR) { + /* \\.\nul */ + result->st_mode = _S_IFCHR; + } else if (fileType == FILE_TYPE_PIPE) { + /* \\.\pipe\spam */ + result->st_mode = _S_IFIFO; + } + /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */ + goto cleanup; + } + + /* Query the reparse tag, and traverse a non-link. */ + if (!traverse) { + if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo, + &tagInfo, sizeof(tagInfo))) { + /* Allow devices that do not support FileAttributeTagInfo. */ + switch (GetLastError()) { + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_FUNCTION: + case ERROR_NOT_SUPPORTED: + tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; + tagInfo.ReparseTag = 0; + break; + default: + retval = -1; + goto cleanup; + } + } else if (tagInfo.FileAttributes & + FILE_ATTRIBUTE_REPARSE_POINT) { + if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) { + if (isUnhandledTag) { + /* Traversing previously failed for either this link + or its target. */ + SetLastError(ERROR_CANT_ACCESS_FILE); + retval = -1; + goto cleanup; + } + /* Traverse a non-link, but not if traversing already failed + for an unhandled tag. */ + } else if (!isUnhandledTag) { + CloseHandle(hFile); + return win32_xstat_impl(path, result, TRUE); } + } + } + + if (!GetFileInformationByHandle(hFile, &fileInfo)) { + switch (GetLastError()) { + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_FUNCTION: + case ERROR_NOT_SUPPORTED: + /* Volumes and physical disks are block devices, e.g. + \\.\C: and \\.\PhysicalDrive0. */ + memset(result, 0, sizeof(*result)); + result->st_mode = 0x6000; /* S_IFBLK */ + goto cleanup; + } + retval = -1; + goto cleanup; + } + } - code = win32_xstat_impl(target_path, result, FALSE); - PyMem_RawFree(target_path); - return code; + _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result); + + if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + /* Fix the file execute permissions. This hack sets S_IEXEC if + the filename has an extension that is commonly used by files + that CreateProcessW can execute. A real implementation calls + GetSecurityInfo, OpenThreadToken/OpenProcessToken, and + AccessCheck to check for generic read, write, and execute + access. */ + const wchar_t *fileExtension = wcsrchr(path, '.'); + if (fileExtension) { + if (_wcsicmp(fileExtension, L".exe") == 0 || + _wcsicmp(fileExtension, L".bat") == 0 || + _wcsicmp(fileExtension, L".cmd") == 0 || + _wcsicmp(fileExtension, L".com") == 0) { + result->st_mode |= 0111; } - } else - CloseHandle(hFile); + } } - _Py_attribute_data_to_stat(&info, reparse_tag, result); - /* Set S_IEXEC if it is an .exe, .bat, ... */ - dot = wcsrchr(path, '.'); - if (dot) { - if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 || - _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0) - result->st_mode |= 0111; +cleanup: + if (hFile != INVALID_HANDLE_VALUE) { + /* Preserve last error if we are failing */ + error = retval ? GetLastError() : 0; + if (!CloseHandle(hFile)) { + retval = -1; + } else if (retval) { + /* Restore last error */ + SetLastError(error); + } } - return 0; + + return retval; } static int @@ -1816,9 +1855,8 @@ win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) default does not traverse symlinks and instead returns attributes for the symlink. - Therefore, win32_lstat will get the attributes traditionally, and - win32_stat will first explicitly resolve the symlink target and then will - call win32_lstat on that result. */ + Instead, we will open the file (which *does* traverse symlinks by default) + and GetFileInformationByHandle(). */ static int win32_lstat(const wchar_t* path, struct _Py_stat_struct *result) @@ -1886,6 +1924,9 @@ static PyStructSequence_Field stat_result_fields[] = { #endif #ifdef HAVE_STRUCT_STAT_ST_FSTYPE {"st_fstype", "Type of filesystem"}, +#endif +#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG + {"st_reparse_tag", "Windows reparse tag"}, #endif {0} }; @@ -1938,6 +1979,12 @@ static PyStructSequence_Field stat_result_fields[] = { #define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX #endif +#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG +#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1) +#else +#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX +#endif + static PyStructSequence_Desc stat_result_desc = { "stat_result", /* name */ stat_result__doc__, /* doc */ @@ -2165,6 +2212,10 @@ _pystat_fromstructstat(STRUCT_STAT *st) PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX, PyUnicode_FromString(st->st_fstype)); #endif +#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG + PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX, + PyLong_FromUnsignedLong(st->st_reparse_tag)); +#endif if (PyErr_Occurred()) { Py_DECREF(v); @@ -3333,83 +3384,99 @@ os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid) static PyObject * posix_getcwd(int use_bytes) { - char *buf, *tmpbuf; - char *cwd; - const size_t chunk = 1024; - size_t buflen = 0; - PyObject *obj; - #ifdef MS_WINDOWS - if (!use_bytes) { - wchar_t wbuf[MAXPATHLEN]; - wchar_t *wbuf2 = wbuf; - PyObject *resobj; - DWORD len; - Py_BEGIN_ALLOW_THREADS - len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf); - /* If the buffer is large enough, len does not include the - terminating \0. If the buffer is too small, len includes - the space needed for the terminator. */ - if (len >= Py_ARRAY_LENGTH(wbuf)) { + wchar_t wbuf[MAXPATHLEN]; + wchar_t *wbuf2 = wbuf; + DWORD len; + + Py_BEGIN_ALLOW_THREADS + len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf); + /* If the buffer is large enough, len does not include the + terminating \0. If the buffer is too small, len includes + the space needed for the terminator. */ + if (len >= Py_ARRAY_LENGTH(wbuf)) { + if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) { wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t)); - if (wbuf2) - len = GetCurrentDirectoryW(len, wbuf2); } - Py_END_ALLOW_THREADS - if (!wbuf2) { - PyErr_NoMemory(); - return NULL; + else { + wbuf2 = NULL; } - if (!len) { - if (wbuf2 != wbuf) - PyMem_RawFree(wbuf2); - return PyErr_SetFromWindowsErr(0); + if (wbuf2) { + len = GetCurrentDirectoryW(len, wbuf2); } - resobj = PyUnicode_FromWideChar(wbuf2, len); + } + Py_END_ALLOW_THREADS + + if (!wbuf2) { + PyErr_NoMemory(); + return NULL; + } + if (!len) { if (wbuf2 != wbuf) PyMem_RawFree(wbuf2); - return resobj; + return PyErr_SetFromWindowsErr(0); } - if (win32_warn_bytes_api()) - return NULL; -#endif + PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len); + if (wbuf2 != wbuf) { + PyMem_RawFree(wbuf2); + } + + if (use_bytes) { + if (resobj == NULL) { + return NULL; + } + Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj)); + } + + return resobj; +#else + const size_t chunk = 1024; + + char *buf = NULL; + char *cwd = NULL; + size_t buflen = 0; - buf = cwd = NULL; Py_BEGIN_ALLOW_THREADS do { - buflen += chunk; -#ifdef MS_WINDOWS - if (buflen > INT_MAX) { - PyErr_NoMemory(); - break; + char *newbuf; + if (buflen <= PY_SSIZE_T_MAX - chunk) { + buflen += chunk; + newbuf = PyMem_RawRealloc(buf, buflen); } -#endif - tmpbuf = PyMem_RawRealloc(buf, buflen); - if (tmpbuf == NULL) + else { + newbuf = NULL; + } + if (newbuf == NULL) { + PyMem_RawFree(buf); + buf = NULL; break; + } + buf = newbuf; - buf = tmpbuf; -#ifdef MS_WINDOWS - cwd = getcwd(buf, (int)buflen); -#else cwd = getcwd(buf, buflen); -#endif } while (cwd == NULL && errno == ERANGE); Py_END_ALLOW_THREADS + if (buf == NULL) { + return PyErr_NoMemory(); + } if (cwd == NULL) { PyMem_RawFree(buf); return posix_error(); } - if (use_bytes) + PyObject *obj; + if (use_bytes) { obj = PyBytes_FromStringAndSize(buf, strlen(buf)); - else + } + else { obj = PyUnicode_DecodeFSDefault(buf); + } PyMem_RawFree(buf); return obj; +#endif /* !MS_WINDOWS */ } @@ -3758,6 +3825,10 @@ static PyObject * os_listdir_impl(PyObject *module, path_t *path) /*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/ { + if (PySys_Audit("os.listdir", "O", + path->object ? path->object : Py_None) < 0) { + return NULL; + } #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) return _listdir_windows_no_opendir(path, NULL); #else @@ -3871,8 +3942,9 @@ os__getfinalpathname_impl(PyObject *module, path_t *path) } result = PyUnicode_FromWideChar(target_path, result_length); - if (path->narrow) + if (result && path->narrow) { Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); + } cleanup: if (target_path != buf) { @@ -3882,44 +3954,6 @@ os__getfinalpathname_impl(PyObject *module, path_t *path) return result; } -/*[clinic input] -os._isdir - - path as arg: object - / - -Return true if the pathname refers to an existing directory. -[clinic start generated code]*/ - -static PyObject * -os__isdir(PyObject *module, PyObject *arg) -/*[clinic end generated code: output=404f334d85d4bf25 input=36cb6785874d479e]*/ -{ - DWORD attributes; - path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0); - - if (!path_converter(arg, &path)) { - if (PyErr_ExceptionMatches(PyExc_ValueError)) { - PyErr_Clear(); - Py_RETURN_FALSE; - } - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - attributes = GetFileAttributesW(path.wide); - Py_END_ALLOW_THREADS - - path_cleanup(&path); - if (attributes == INVALID_FILE_ATTRIBUTES) - Py_RETURN_FALSE; - - if (attributes & FILE_ATTRIBUTE_DIRECTORY) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - /*[clinic input] os._getvolumepathname @@ -4282,7 +4316,7 @@ os_system_impl(PyObject *module, const Py_UNICODE *command) { long result; - if (PySys_Audit("system", "(u)", command) < 0) { + if (PySys_Audit("os.system", "(u)", command) < 0) { return -1; } @@ -4309,7 +4343,7 @@ os_system_impl(PyObject *module, PyObject *command) long result; const char *bytes = PyBytes_AsString(command); - if (PySys_Audit("system", "(O)", command) < 0) { + if (PySys_Audit("os.system", "(O)", command) < 0) { return -1; } @@ -4705,7 +4739,7 @@ split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns) os.utime path: path_t(allow_fd='PATH_UTIME_HAVE_FD') - times: object = NULL + times: object = None * ns: object = NULL dir_fd: dir_fd(requires='futimensat') = None @@ -4742,7 +4776,7 @@ dir_fd and follow_symlinks may not be available on your platform. static PyObject * os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, int dir_fd, int follow_symlinks) -/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/ +/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/ { #ifdef MS_WINDOWS HANDLE hFile; @@ -4755,14 +4789,14 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, memset(&utime, 0, sizeof(utime_t)); - if (times && (times != Py_None) && ns) { + if (times != Py_None && ns) { PyErr_SetString(PyExc_ValueError, "utime: you may specify either 'times'" " or 'ns' but not both"); return NULL; } - if (times && (times != Py_None)) { + if (times != Py_None) { time_t a_sec, m_sec; long a_nsec, m_nsec; if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) { @@ -5371,7 +5405,7 @@ parse_file_actions(PyObject *file_actions, return -1; } - for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) { + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) { file_action = PySequence_Fast_GET_ITEM(seq, i); Py_INCREF(file_action); if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) { @@ -6407,6 +6441,9 @@ os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask) } CPU_SET_S(cpu, setsize, cpu_set); } + if (PyErr_Occurred()) { + goto error; + } Py_CLEAR(iterator); if (sched_setaffinity(pid, setsize, cpu_set)) { @@ -6722,6 +6759,13 @@ os_getpid_impl(PyObject *module) } #endif /* HAVE_GETPID */ +#ifdef NGROUPS_MAX +#define MAX_GROUPS NGROUPS_MAX +#else + /* defined to be 16 on Solaris7, so this should be a small number */ +#define MAX_GROUPS 64 +#endif + #ifdef HAVE_GETGROUPLIST /* AC 3.5: funny apple logic below */ @@ -6734,13 +6778,6 @@ Returns a list of groups to which a user belongs.\n\n\ static PyObject * posix_getgrouplist(PyObject *self, PyObject *args) { -#ifdef NGROUPS_MAX -#define MAX_GROUPS NGROUPS_MAX -#else - /* defined to be 16 on Solaris7, so this should be a small number */ -#define MAX_GROUPS 64 -#endif - const char *user; int i, ngroups; PyObject *list; @@ -6749,7 +6786,16 @@ posix_getgrouplist(PyObject *self, PyObject *args) #else gid_t *groups, basegid; #endif - ngroups = MAX_GROUPS; + + /* + * NGROUPS_MAX is defined by POSIX.1 as the maximum + * number of supplimental groups a users can belong to. + * We have to increment it by one because + * getgrouplist() returns both the supplemental groups + * and the primary group, i.e. all of the groups the + * user belongs to. + */ + ngroups = 1 + MAX_GROUPS; #ifdef __APPLE__ if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid)) @@ -6818,13 +6864,6 @@ os_getgroups_impl(PyObject *module) /*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/ { PyObject *result = NULL; - -#ifdef NGROUPS_MAX -#define MAX_GROUPS NGROUPS_MAX -#else - /* defined to be 16 on Solaris7, so this should be a small number */ -#define MAX_GROUPS 64 -#endif gid_t grouplist[MAX_GROUPS]; /* On MacOSX getgroups(2) can return more than MAX_GROUPS results @@ -7785,12 +7824,11 @@ os_readlink_impl(PyObject *module, path_t *path, int dir_fd) return PyBytes_FromStringAndSize(buffer, length); #elif defined(MS_WINDOWS) DWORD n_bytes_returned; - DWORD io_result; + DWORD io_result = 0; HANDLE reparse_point_handle; char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer; - const wchar_t *print_name; - PyObject *result; + PyObject *result = NULL; /* First get a handle to the reparse point */ Py_BEGIN_ALLOW_THREADS @@ -7802,42 +7840,51 @@ os_readlink_impl(PyObject *module, path_t *path, int dir_fd) OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0); - Py_END_ALLOW_THREADS - - if (reparse_point_handle == INVALID_HANDLE_VALUE) { - return path_error(path); + if (reparse_point_handle != INVALID_HANDLE_VALUE) { + /* New call DeviceIoControl to read the reparse point */ + io_result = DeviceIoControl( + reparse_point_handle, + FSCTL_GET_REPARSE_POINT, + 0, 0, /* in buffer */ + target_buffer, sizeof(target_buffer), + &n_bytes_returned, + 0 /* we're not using OVERLAPPED_IO */ + ); + CloseHandle(reparse_point_handle); } - - Py_BEGIN_ALLOW_THREADS - /* New call DeviceIoControl to read the reparse point */ - io_result = DeviceIoControl( - reparse_point_handle, - FSCTL_GET_REPARSE_POINT, - 0, 0, /* in buffer */ - target_buffer, sizeof(target_buffer), - &n_bytes_returned, - 0 /* we're not using OVERLAPPED_IO */ - ); - CloseHandle(reparse_point_handle); Py_END_ALLOW_THREADS if (io_result == 0) { return path_error(path); } - if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) + wchar_t *name = NULL; + Py_ssize_t nameLen = 0; + if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK) { - PyErr_SetString(PyExc_ValueError, - "not a symbolic link"); - return NULL; + name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer + + rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset); + nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t); } - print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer + - rdb->SymbolicLinkReparseBuffer.PrintNameOffset); - - result = PyUnicode_FromWideChar(print_name, - rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t)); - if (path->narrow) { - Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); + else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) + { + name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer + + rdb->MountPointReparseBuffer.SubstituteNameOffset); + nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t); + } + else + { + PyErr_SetString(PyExc_ValueError, "not a symbolic link"); + } + if (name) { + if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) { + /* Our buffer is mutable, so this is okay */ + name[1] = L'\\'; + } + result = PyUnicode_FromWideChar(name, nameLen); + if (result && path->narrow) { + Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); + } } return result; #endif @@ -8372,6 +8419,21 @@ os_close_impl(PyObject *module, int fd) } +#ifdef HAVE_FDWALK +static int +_fdwalk_close_func(void *lohi, int fd) +{ + int lo = ((int *)lohi)[0]; + int hi = ((int *)lohi)[1]; + + if (fd >= hi) + return 1; + else if (fd >= lo) + close(fd); + return 0; +} +#endif /* HAVE_FDWALK */ + /*[clinic input] os.closerange @@ -8386,11 +8448,21 @@ static PyObject * os_closerange_impl(PyObject *module, int fd_low, int fd_high) /*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/ { +#ifdef HAVE_FDWALK + int lohi[2]; +#else int i; +#endif Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH +#ifdef HAVE_FDWALK + lohi[0] = Py_MAX(fd_low, 0); + lohi[1] = fd_high; + fdwalk(_fdwalk_close_func, lohi); +#else for (i = Py_MAX(fd_low, 0); i < fd_high; i++) close(i); +#endif _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS Py_RETURN_NONE; @@ -11504,8 +11576,6 @@ os.startfile filepath: path_t operation: Py_UNICODE = NULL -startfile(filepath [, operation]) - Start a file with its associated application. When "operation" is not specified or "open", this acts like @@ -11527,7 +11597,7 @@ the underlying Win32 ShellExecute function doesn't work if it is. static PyObject * os_startfile_impl(PyObject *module, path_t *filepath, const Py_UNICODE *operation) -/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/ +/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/ { HINSTANCE rc; @@ -12129,23 +12199,9 @@ os_cpu_count_impl(PyObject *module) { int ncpu = 0; #ifdef MS_WINDOWS - /* Vista is supported and the GetMaximumProcessorCount API is Win7+ - Need to fallback to Vista behavior if this call isn't present */ - HINSTANCE hKernel32; - static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL; - Py_BEGIN_ALLOW_THREADS - hKernel32 = GetModuleHandleW(L"KERNEL32"); - *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32, - "GetMaximumProcessorCount"); - Py_END_ALLOW_THREADS - if (_GetMaximumProcessorCount != NULL) { - ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS); - } - else { - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - ncpu = sysinfo.dwNumberOfProcessors; - } + /* Declare prototype here to avoid pulling in all of the Win7 APIs in 3.8 */ + DWORD WINAPI GetActiveProcessorCount(WORD group); + ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS); #elif defined(__hpux) ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL); #elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) @@ -13161,6 +13217,11 @@ os_scandir_impl(PyObject *module, path_t *path) #endif #endif + if (PySys_Audit("os.scandir", "O", + path->object ? path->object : Py_None) < 0) { + return NULL; + } + iterator = PyObject_New(ScandirIterator, &ScandirIteratorType); if (!iterator) return NULL; @@ -13631,7 +13692,6 @@ static PyMethodDef posix_methods[] = { OS_PATHCONF_METHODDEF OS_ABORT_METHODDEF OS__GETFULLPATHNAME_METHODDEF - OS__ISDIR_METHODDEF OS__GETDISKUSAGE_METHODDEF OS__GETFINALPATHNAME_METHODDEF OS__GETVOLUMEPATHNAME_METHODDEF diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 45a1e684d19fe8..df1a69b653b353 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -810,7 +810,9 @@ pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyObject *file) PyObject *readmethod = NULL; _Py_IDENTIFIER(read); - readmethod = _PyObject_GetAttrId(file, &PyId_read); + if (_PyObject_LookupAttrId(file, &PyId_read, &readmethod) < 0) { + return NULL; + } if (readmethod == NULL) { PyErr_SetString(PyExc_TypeError, "argument must have 'read' attribute"); @@ -1501,8 +1503,8 @@ static PyTypeObject Xmlparsetype = { /*[clinic input] pyexpat.ParserCreate - encoding: str(accept={str, NoneType}) = NULL - namespace_separator: str(accept={str, NoneType}) = NULL + encoding: str(accept={str, NoneType}) = None + namespace_separator: str(accept={str, NoneType}) = None intern: object = NULL Return a new XML parser object. @@ -1511,7 +1513,7 @@ Return a new XML parser object. static PyObject * pyexpat_ParserCreate_impl(PyObject *module, const char *encoding, const char *namespace_separator, PyObject *intern) -/*[clinic end generated code: output=295c0cf01ab1146c input=23d29704acad385d]*/ +/*[clinic end generated code: output=295c0cf01ab1146c input=e8da8e8d7122cb5d]*/ { PyObject *result; int intern_decref = 0; diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 7698984ff3afe1..9aca70599689b6 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1329,7 +1329,7 @@ static struct PyModuleDef signalmodule = { PyMODINIT_FUNC PyInit__signal(void) { - PyObject *m, *d, *x; + PyObject *m, *d; int i; /* Create the module and add the functions */ @@ -1350,13 +1350,17 @@ PyInit__signal(void) /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); - x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL); - if (PyModule_AddObject(m, "SIG_DFL", x)) + DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL); + if (!DefaultHandler || + PyDict_SetItemString(d, "SIG_DFL", DefaultHandler) < 0) { goto finally; + } - x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN); - if (PyModule_AddObject(m, "SIG_IGN", x)) + IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN); + if (!IgnoreHandler || + PyDict_SetItemString(d, "SIG_IGN", IgnoreHandler) < 0) { goto finally; + } if (PyModule_AddIntMacro(m, NSIG)) goto finally; @@ -1374,8 +1378,8 @@ PyInit__signal(void) goto finally; #endif - x = IntHandler = PyDict_GetItemString(d, "default_int_handler"); - if (!x) + IntHandler = PyDict_GetItemString(d, "default_int_handler"); + if (!IntHandler) goto finally; Py_INCREF(IntHandler); @@ -1568,8 +1572,10 @@ PyInit__signal(void) #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) ItimerError = PyErr_NewException("signal.ItimerError", PyExc_OSError, NULL); - if (PyModule_AddObject(m, "ItimerError", ItimerError)) + if (!ItimerError || + PyDict_SetItemString(d, "ItimerError", ItimerError) < 0) { goto finally; + } #endif #ifdef CTRL_C_EVENT @@ -1615,6 +1621,9 @@ finisignal(void) Py_CLEAR(IntHandler); Py_CLEAR(DefaultHandler); Py_CLEAR(IgnoreHandler); +#ifdef HAVE_GETITIMER + Py_CLEAR(ItimerError); +#endif } diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 36d13e768cd378..594a0d6efad197 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -780,6 +780,17 @@ internal_select(PySocketSockObject *s, int writing, _PyTime_t interval, ms = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING); assert(ms <= INT_MAX); + /* On some OSes, typically BSD-based ones, the timeout parameter of the + poll() syscall, when negative, must be exactly INFTIM, where defined, + or -1. See issue 37811. */ + if (ms < 0) { +#ifdef INFTIM + ms = INFTIM; +#else + ms = -1; +#endif + } + Py_BEGIN_ALLOW_THREADS; n = poll(&pollfd, 1, (int)ms); Py_END_ALLOW_THREADS; @@ -1513,7 +1524,7 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) #endif /* CAN_ISOTP */ default: { - return Py_BuildValue("O&", PyUnicode_DecodeFSDefault, + return Py_BuildValue("(O&)", PyUnicode_DecodeFSDefault, ifname); } } @@ -7656,6 +7667,8 @@ PyInit__socket(void) #endif #ifdef HAVE_LINUX_CAN_BCM_H PyModule_AddIntMacro(m, CAN_BCM); + + /* BCM opcodes */ PyModule_AddIntConstant(m, "CAN_BCM_TX_SETUP", TX_SETUP); PyModule_AddIntConstant(m, "CAN_BCM_TX_DELETE", TX_DELETE); PyModule_AddIntConstant(m, "CAN_BCM_TX_READ", TX_READ); @@ -7668,6 +7681,23 @@ PyInit__socket(void) PyModule_AddIntConstant(m, "CAN_BCM_RX_STATUS", RX_STATUS); PyModule_AddIntConstant(m, "CAN_BCM_RX_TIMEOUT", RX_TIMEOUT); PyModule_AddIntConstant(m, "CAN_BCM_RX_CHANGED", RX_CHANGED); + + /* BCM flags */ + PyModule_AddIntConstant(m, "CAN_BCM_SETTIMER", SETTIMER); + PyModule_AddIntConstant(m, "CAN_BCM_STARTTIMER", STARTTIMER); + PyModule_AddIntConstant(m, "CAN_BCM_TX_COUNTEVT", TX_COUNTEVT); + PyModule_AddIntConstant(m, "CAN_BCM_TX_ANNOUNCE", TX_ANNOUNCE); + PyModule_AddIntConstant(m, "CAN_BCM_TX_CP_CAN_ID", TX_CP_CAN_ID); + PyModule_AddIntConstant(m, "CAN_BCM_RX_FILTER_ID", RX_FILTER_ID); + PyModule_AddIntConstant(m, "CAN_BCM_RX_CHECK_DLC", RX_CHECK_DLC); + PyModule_AddIntConstant(m, "CAN_BCM_RX_NO_AUTOTIMER", RX_NO_AUTOTIMER); + PyModule_AddIntConstant(m, "CAN_BCM_RX_ANNOUNCE_RESUME", RX_ANNOUNCE_RESUME); + PyModule_AddIntConstant(m, "CAN_BCM_TX_RESET_MULTI_IDX", TX_RESET_MULTI_IDX); + PyModule_AddIntConstant(m, "CAN_BCM_RX_RTR_FRAME", RX_RTR_FRAME); +#ifdef CAN_FD_FRAME + /* CAN_FD_FRAME was only introduced in the 4.8.x kernel series */ + PyModule_AddIntConstant(m, "CAN_BCM_CAN_FD_FRAME", CAN_FD_FRAME); +#endif #endif #ifdef SOL_RDS PyModule_AddIntMacro(m, SOL_RDS); diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c index d66cb44f69bdfe..9180f185e1e877 100644 --- a/Modules/symtablemodule.c +++ b/Modules/symtablemodule.c @@ -30,11 +30,10 @@ _symtable_symtable_impl(PyObject *module, PyObject *source, struct symtable *st; PyObject *t; int start; - PyCompilerFlags cf; + PyCompilerFlags cf = _PyCompilerFlags_INIT; PyObject *source_copy = NULL; cf.cf_flags = PyCF_SOURCE_IS_UTF8; - cf.cf_feature_version = PY_MINOR_VERSION; const char *str = _Py_SourceAsString(source, "symtable", "string or bytes", &cf, &source_copy); if (str == NULL) { diff --git a/Modules/termios.c b/Modules/termios.c index 7601b68afda3c9..aee7f12c57cab5 100644 --- a/Modules/termios.c +++ b/Modules/termios.c @@ -18,7 +18,7 @@ #include /* HP-UX requires that this be included to pick up MDCD, MCTS, MDSR, - * MDTR, MRI, and MRTS (appearantly used internally by some things + * MDTR, MRI, and MRTS (apparently used internally by some things * defined as macros; these are not used here directly). */ #ifdef HAVE_SYS_MODEM_H diff --git a/Modules/timemodule.c b/Modules/timemodule.c index f991f31ee15ed7..5e0010c8a81996 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -1208,7 +1208,7 @@ _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) return -1; } - _PyTime_t total = utime + utime; + _PyTime_t total = utime + stime; *tp = total; return 0; } @@ -1581,6 +1581,19 @@ init_timezone(PyObject *m) PyModule_AddIntConstant(m, "altzone", _Py_timezone-3600); #endif PyModule_AddIntConstant(m, "daylight", _Py_daylight); +#ifdef MS_WINDOWS + TIME_ZONE_INFORMATION tzinfo = {0}; + GetTimeZoneInformation(&tzinfo); + otz0 = PyUnicode_FromWideChar(tzinfo.StandardName, -1); + if (otz0 == NULL) { + return -1; + } + otz1 = PyUnicode_FromWideChar(tzinfo.DaylightName, -1); + if (otz1 == NULL) { + Py_DECREF(otz0); + return -1; + } +#else otz0 = PyUnicode_DecodeLocale(_Py_tzname[0], "surrogateescape"); if (otz0 == NULL) { return -1; @@ -1590,6 +1603,7 @@ init_timezone(PyObject *m) Py_DECREF(otz0); return -1; } +#endif // MS_WINDOWS PyObject *tzname_obj = Py_BuildValue("(NN)", otz0, otz1); if (tzname_obj == NULL) { return -1; diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index ae0d4e46f9a409..5e8ba602d66848 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -19,6 +19,8 @@ #include "ucnhash.h" #include "structmember.h" +#include + _Py_IDENTIFIER(NFC); _Py_IDENTIFIER(NFD); _Py_IDENTIFIER(NFKC); @@ -775,25 +777,40 @@ nfc_nfkc(PyObject *self, PyObject *input, int k) return result; } -typedef enum {YES, NO, MAYBE} NormalMode; - -/* Return YES if the input is certainly normalized, NO or MAYBE if it might not be. */ -static NormalMode -is_normalized(PyObject *self, PyObject *input, int nfc, int k) +// This needs to match the logic in makeunicodedata.py +// which constructs the quickcheck data. +typedef enum {YES = 0, MAYBE = 1, NO = 2} QuickcheckResult; + +/* Run the Unicode normalization "quickcheck" algorithm. + * + * Return YES or NO if quickcheck determines the input is certainly + * normalized or certainly not, and MAYBE if quickcheck is unable to + * tell. + * + * If `yes_only` is true, then return MAYBE as soon as we determine + * the answer is not YES. + * + * For background and details on the algorithm, see UAX #15: + * https://www.unicode.org/reports/tr15/#Detecting_Normalization_Forms + */ +static QuickcheckResult +is_normalized_quickcheck(PyObject *self, PyObject *input, + int nfc, int k, bool yes_only) { - Py_ssize_t i, len; - int kind; - void *data; - unsigned char prev_combining = 0, quickcheck_mask; - /* An older version of the database is requested, quickchecks must be disabled. */ if (self && UCD_Check(self)) return NO; - /* The two quickcheck bits at this shift mean 0=Yes, 1=Maybe, 2=No, - as described in http://unicode.org/reports/tr15/#Annex8. */ - quickcheck_mask = 3 << ((nfc ? 4 : 0) + (k ? 2 : 0)); + Py_ssize_t i, len; + int kind; + void *data; + unsigned char prev_combining = 0; + + /* The two quickcheck bits at this shift have type QuickcheckResult. */ + int quickcheck_shift = (nfc ? 4 : 0) + (k ? 2 : 0); + + QuickcheckResult result = YES; /* certainly normalized, unless we find something */ i = 0; kind = PyUnicode_KIND(input); @@ -802,16 +819,26 @@ is_normalized(PyObject *self, PyObject *input, int nfc, int k) while (i < len) { Py_UCS4 ch = PyUnicode_READ(kind, data, i++); const _PyUnicode_DatabaseRecord *record = _getrecord_ex(ch); - unsigned char combining = record->combining; - unsigned char quickcheck = record->normalization_quick_check; - if (quickcheck & quickcheck_mask) - return MAYBE; /* this string might need normalization */ + unsigned char combining = record->combining; if (combining && prev_combining > combining) return NO; /* non-canonical sort order, not normalized */ prev_combining = combining; + + unsigned char quickcheck_whole = record->normalization_quick_check; + if (yes_only) { + if (quickcheck_whole & (3 << quickcheck_shift)) + return MAYBE; + } else { + switch ((quickcheck_whole >> quickcheck_shift) & 3) { + case NO: + return NO; + case MAYBE: + result = MAYBE; /* this string might need normalization */ + } + } } - return YES; /* certainly normalized */ + return result; } /*[clinic input] @@ -844,7 +871,7 @@ unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form, PyObject *result; int nfc = 0; int k = 0; - NormalMode m; + QuickcheckResult m; PyObject *cmp; int match = 0; @@ -867,7 +894,7 @@ unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form, return NULL; } - m = is_normalized(self, input, nfc, k); + m = is_normalized_quickcheck(self, input, nfc, k, false); if (m == MAYBE) { cmp = (nfc ? nfc_nfkc : nfd_nfkd)(self, input, k); @@ -913,28 +940,28 @@ unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form, } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFC)) { - if (is_normalized(self, input, 1, 0) == YES) { + if (is_normalized_quickcheck(self, input, 1, 0, true) == YES) { Py_INCREF(input); return input; } return nfc_nfkc(self, input, 0); } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKC)) { - if (is_normalized(self, input, 1, 1) == YES) { + if (is_normalized_quickcheck(self, input, 1, 1, true) == YES) { Py_INCREF(input); return input; } return nfc_nfkc(self, input, 1); } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFD)) { - if (is_normalized(self, input, 0, 0) == YES) { + if (is_normalized_quickcheck(self, input, 0, 0, true) == YES) { Py_INCREF(input); return input; } return nfd_nfkd(self, input, 0); } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKD)) { - if (is_normalized(self, input, 0, 1) == YES) { + if (is_normalized_quickcheck(self, input, 0, 1, true) == YES) { Py_INCREF(input); return input; } diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index c684db76736462..590b8060561868 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1698,6 +1698,10 @@ bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints) } Py_DECREF(bytearray_obj); + if (PyErr_Occurred()) { + return NULL; + } + Py_RETURN_NONE; } @@ -2059,9 +2063,10 @@ _common_reduce(PyByteArrayObject *self, int proto) _Py_IDENTIFIER(__dict__); char *buf; - dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__); + if (_PyObject_LookupAttrId((PyObject *)self, &PyId___dict__, &dict) < 0) { + return NULL; + } if (dict == NULL) { - PyErr_Clear(); dict = Py_None; Py_INCREF(dict); } diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 37c5f7dbc8040b..7d131842059228 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -743,7 +743,7 @@ tailmatch(const char *str, Py_ssize_t len, PyObject *substr, if (direction < 0) { /* startswith */ - if (start + slen > len) + if (start > len - slen) goto notfound; } else { /* endswith */ diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 06c87b0c62d3bb..feeabcb8b4c7ad 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -667,9 +667,6 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, Py_ssize_t len = 0; char onechar; /* For byte_converter() */ Py_ssize_t alloc; -#ifdef Py_DEBUG - char *before; -#endif fmt++; if (*fmt == '%') { @@ -981,8 +978,8 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, if (res == NULL) goto error; } -#ifdef Py_DEBUG - before = res; +#ifndef NDEBUG + char *before = res; #endif /* Write the sign if needed */ @@ -1047,7 +1044,7 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, } Py_XDECREF(temp); -#ifdef Py_DEBUG +#ifndef NDEBUG /* check that we computed the exact size for this write */ assert((res - before) == alloc); #endif @@ -2004,7 +2001,7 @@ do_strip(PyBytesObject *self, int striptype) Py_LOCAL_INLINE(PyObject *) do_argstrip(PyBytesObject *self, int striptype, PyObject *bytes) { - if (bytes != NULL && bytes != Py_None) { + if (bytes != Py_None) { return do_xstrip(self, striptype, bytes); } return do_strip(self, striptype); @@ -2939,7 +2936,6 @@ PyBytes_Concat(PyObject **pv, PyObject *w) Py_ssize_t oldsize; Py_buffer wb; - wb.len = -1; if (PyObject_GetBuffer(w, &wb, PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", Py_TYPE(w)->tp_name, Py_TYPE(*pv)->tp_name); @@ -3226,8 +3222,9 @@ _PyBytesWriter_Init(_PyBytesWriter *writer) { /* Set all attributes before small_buffer to 0 */ memset(writer, 0, offsetof(_PyBytesWriter, small_buffer)); -#ifdef Py_DEBUG - memset(writer->small_buffer, 0xCB, sizeof(writer->small_buffer)); +#ifndef NDEBUG + memset(writer->small_buffer, PYMEM_CLEANBYTE, + sizeof(writer->small_buffer)); #endif } @@ -3264,10 +3261,10 @@ _PyBytesWriter_GetSize(_PyBytesWriter *writer, char *str) return str - start; } -Py_LOCAL_INLINE(void) +#ifndef NDEBUG +Py_LOCAL_INLINE(int) _PyBytesWriter_CheckConsistency(_PyBytesWriter *writer, char *str) { -#ifdef Py_DEBUG char *start, *end; if (writer->use_small_buffer) { @@ -3297,15 +3294,16 @@ _PyBytesWriter_CheckConsistency(_PyBytesWriter *writer, char *str) end = start + writer->allocated; assert(str != NULL); assert(start <= str && str <= end); -#endif + return 1; } +#endif void* _PyBytesWriter_Resize(_PyBytesWriter *writer, void *str, Py_ssize_t size) { Py_ssize_t allocated, pos; - _PyBytesWriter_CheckConsistency(writer, str); + assert(_PyBytesWriter_CheckConsistency(writer, str)); assert(writer->allocated < size); allocated = size; @@ -3354,14 +3352,15 @@ _PyBytesWriter_Resize(_PyBytesWriter *writer, void *str, Py_ssize_t size) } writer->use_small_buffer = 0; -#ifdef Py_DEBUG - memset(writer->small_buffer, 0xDB, sizeof(writer->small_buffer)); +#ifndef NDEBUG + memset(writer->small_buffer, PYMEM_CLEANBYTE, + sizeof(writer->small_buffer)); #endif } writer->allocated = allocated; str = _PyBytesWriter_AsString(writer) + pos; - _PyBytesWriter_CheckConsistency(writer, str); + assert(_PyBytesWriter_CheckConsistency(writer, str)); return str; error: @@ -3374,7 +3373,7 @@ _PyBytesWriter_Prepare(_PyBytesWriter *writer, void *str, Py_ssize_t size) { Py_ssize_t new_min_size; - _PyBytesWriter_CheckConsistency(writer, str); + assert(_PyBytesWriter_CheckConsistency(writer, str)); assert(size >= 0); if (size == 0) { @@ -3407,7 +3406,7 @@ _PyBytesWriter_Alloc(_PyBytesWriter *writer, Py_ssize_t size) assert(size >= 0); writer->use_small_buffer = 1; -#ifdef Py_DEBUG +#ifndef NDEBUG writer->allocated = sizeof(writer->small_buffer) - 1; /* In debug mode, don't use the full small buffer because it is less efficient than bytes and bytearray objects to detect buffer underflow @@ -3435,7 +3434,7 @@ _PyBytesWriter_Finish(_PyBytesWriter *writer, void *str) Py_ssize_t size; PyObject *result; - _PyBytesWriter_CheckConsistency(writer, str); + assert(_PyBytesWriter_CheckConsistency(writer, str)); size = _PyBytesWriter_GetSize(writer, str); if (size == 0 && !writer->use_bytearray) { diff --git a/Objects/call.c b/Objects/call.c index 578e1b3ab61933..c66389854d8bf0 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -176,7 +176,7 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) /* get vectorcallfunc as in _PyVectorcall_Function, but without * the _Py_TPFLAGS_HAVE_VECTORCALL check */ Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset; - if ((offset <= 0) || (!Py_TYPE(callable)->tp_call)) { + if (offset <= 0) { PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall", Py_TYPE(callable)->tp_name); return NULL; @@ -206,7 +206,7 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) Py_DECREF(kwnames); } - return result; + return _Py_CheckFunctionResult(callable, result, NULL); } @@ -723,25 +723,6 @@ _PyMethodDef_RawFastCallKeywords(PyMethodDef *method, PyObject *self, } -PyObject * -_PyCFunction_Vectorcall(PyObject *func, - PyObject *const *args, size_t nargsf, - PyObject *kwnames) -{ - PyObject *result; - - assert(func != NULL); - assert(PyCFunction_Check(func)); - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - - result = _PyMethodDef_RawFastCallKeywords(((PyCFunctionObject*)func)->m_ml, - PyCFunction_GET_SELF(func), - args, nargs, kwnames); - result = _Py_CheckFunctionResult(func, result, NULL); - return result; -} - - static PyObject * cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs) { diff --git a/Objects/classobject.c b/Objects/classobject.c index ffd3f875c0e7ba..12bb836cb716c0 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -62,18 +62,34 @@ method_vectorcall(PyObject *method, PyObject *const *args, } else { Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); - PyObject **newargs; Py_ssize_t totalargs = nargs + nkwargs; - newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *)); - if (newargs == NULL) { - PyErr_NoMemory(); - return NULL; + if (totalargs == 0) { + return _PyObject_Vectorcall(func, &self, 1, NULL); + } + + PyObject *newargs_stack[_PY_FASTCALL_SMALL_STACK]; + PyObject **newargs; + if (totalargs <= (Py_ssize_t)Py_ARRAY_LENGTH(newargs_stack) - 1) { + newargs = newargs_stack; + } + else { + newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *)); + if (newargs == NULL) { + PyErr_NoMemory(); + return NULL; + } } /* use borrowed references */ newargs[0] = self; + /* bpo-37138: since totalargs > 0, it's impossible that args is NULL. + * We need this, since calling memcpy() with a NULL pointer is + * undefined behaviour. */ + assert(args != NULL); memcpy(newargs + 1, args, totalargs * sizeof(PyObject *)); result = _PyObject_Vectorcall(func, newargs, nargs+1, kwnames); - PyMem_Free(newargs); + if (newargs != newargs_stack) { + PyMem_Free(newargs); + } } return result; } diff --git a/Objects/clinic/bytearrayobject.c.h b/Objects/clinic/bytearrayobject.c.h index 08c6eb53f5878a..05577077a5f8d4 100644 --- a/Objects/clinic/bytearrayobject.c.h +++ b/Objects/clinic/bytearrayobject.c.h @@ -115,14 +115,14 @@ bytearray_maketrans(void *null, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&frm, 'C')) { - _PyArg_BadArgument("maketrans", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("maketrans", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyObject_GetBuffer(args[1], &to, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&to, 'C')) { - _PyArg_BadArgument("maketrans", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("maketrans", "argument 2", "contiguous buffer", args[1]); goto exit; } return_value = bytearray_maketrans_impl(&frm, &to); @@ -175,14 +175,14 @@ bytearray_replace(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nar goto exit; } if (!PyBuffer_IsContiguous(&old, 'C')) { - _PyArg_BadArgument("replace", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("replace", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyObject_GetBuffer(args[1], &new, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&new, 'C')) { - _PyArg_BadArgument("replace", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("replace", "argument 2", "contiguous buffer", args[1]); goto exit; } if (nargs < 3) { @@ -735,7 +735,7 @@ bytearray_decode(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t narg } if (args[0]) { if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("decode", 1, "str", args[0]); + _PyArg_BadArgument("decode", "argument 'encoding'", "str", args[0]); goto exit; } Py_ssize_t encoding_length; @@ -752,7 +752,7 @@ bytearray_decode(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t narg } } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("decode", 2, "str", args[1]); + _PyArg_BadArgument("decode", "argument 'errors'", "str", args[1]); goto exit; } Py_ssize_t errors_length; @@ -854,7 +854,7 @@ bytearray_fromhex(PyTypeObject *type, PyObject *arg) PyObject *string; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("fromhex", 0, "str", arg); + _PyArg_BadArgument("fromhex", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -868,7 +868,7 @@ bytearray_fromhex(PyTypeObject *type, PyObject *arg) } PyDoc_STRVAR(bytearray_hex__doc__, -"hex($self, /, sep=None, bytes_per_sep=1)\n" +"hex($self, /, sep=, bytes_per_sep=1)\n" "--\n" "\n" "Create a str of hexadecimal numbers from a bytearray object.\n" @@ -1011,4 +1011,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) { return bytearray_sizeof_impl(self); } -/*[clinic end generated code: output=7848247e5469ba1b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=508dce79cf2dffcc input=a9049054013a1b77]*/ diff --git a/Objects/clinic/bytesobject.c.h b/Objects/clinic/bytesobject.c.h index 69c35063c6cf76..22024ab155c8ec 100644 --- a/Objects/clinic/bytesobject.c.h +++ b/Objects/clinic/bytesobject.c.h @@ -99,7 +99,7 @@ bytes_partition(PyBytesObject *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&sep, 'C')) { - _PyArg_BadArgument("partition", 0, "contiguous buffer", arg); + _PyArg_BadArgument("partition", "argument", "contiguous buffer", arg); goto exit; } return_value = bytes_partition_impl(self, &sep); @@ -142,7 +142,7 @@ bytes_rpartition(PyBytesObject *self, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&sep, 'C')) { - _PyArg_BadArgument("rpartition", 0, "contiguous buffer", arg); + _PyArg_BadArgument("rpartition", "argument", "contiguous buffer", arg); goto exit; } return_value = bytes_rpartition_impl(self, &sep); @@ -420,14 +420,14 @@ bytes_maketrans(void *null, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&frm, 'C')) { - _PyArg_BadArgument("maketrans", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("maketrans", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyObject_GetBuffer(args[1], &to, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&to, 'C')) { - _PyArg_BadArgument("maketrans", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("maketrans", "argument 2", "contiguous buffer", args[1]); goto exit; } return_value = bytes_maketrans_impl(&frm, &to); @@ -480,14 +480,14 @@ bytes_replace(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&old, 'C')) { - _PyArg_BadArgument("replace", 1, "contiguous buffer", args[0]); + _PyArg_BadArgument("replace", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyObject_GetBuffer(args[1], &new, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&new, 'C')) { - _PyArg_BadArgument("replace", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("replace", "argument 2", "contiguous buffer", args[1]); goto exit; } if (nargs < 3) { @@ -568,7 +568,7 @@ bytes_decode(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObj } if (args[0]) { if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("decode", 1, "str", args[0]); + _PyArg_BadArgument("decode", "argument 'encoding'", "str", args[0]); goto exit; } Py_ssize_t encoding_length; @@ -585,7 +585,7 @@ bytes_decode(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("decode", 2, "str", args[1]); + _PyArg_BadArgument("decode", "argument 'errors'", "str", args[1]); goto exit; } Py_ssize_t errors_length; @@ -674,7 +674,7 @@ bytes_fromhex(PyTypeObject *type, PyObject *arg) PyObject *string; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("fromhex", 0, "str", arg); + _PyArg_BadArgument("fromhex", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -688,7 +688,7 @@ bytes_fromhex(PyTypeObject *type, PyObject *arg) } PyDoc_STRVAR(bytes_hex__doc__, -"hex($self, /, sep=None, bytes_per_sep=1)\n" +"hex($self, /, sep=, bytes_per_sep=1)\n" "--\n" "\n" "Create a str of hexadecimal numbers from a bytes object.\n" @@ -755,4 +755,4 @@ bytes_hex(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject exit: return return_value; } -/*[clinic end generated code: output=2d0a3733e13e753a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ca60dfccf8d51e88 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/codeobject.c.h b/Objects/clinic/codeobject.c.h index ec127ce1718980..6596de051cacb3 100644 --- a/Objects/clinic/codeobject.c.h +++ b/Objects/clinic/codeobject.c.h @@ -158,7 +158,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } if (args[7]) { if (!PyBytes_Check(args[7])) { - _PyArg_BadArgument("replace", 8, "bytes", args[7]); + _PyArg_BadArgument("replace", "argument 'co_code'", "bytes", args[7]); goto exit; } co_code = (PyBytesObject *)args[7]; @@ -168,7 +168,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } if (args[8]) { if (!PyTuple_Check(args[8])) { - _PyArg_BadArgument("replace", 9, "tuple", args[8]); + _PyArg_BadArgument("replace", "argument 'co_consts'", "tuple", args[8]); goto exit; } co_consts = args[8]; @@ -178,7 +178,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } if (args[9]) { if (!PyTuple_Check(args[9])) { - _PyArg_BadArgument("replace", 10, "tuple", args[9]); + _PyArg_BadArgument("replace", "argument 'co_names'", "tuple", args[9]); goto exit; } co_names = args[9]; @@ -188,7 +188,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } if (args[10]) { if (!PyTuple_Check(args[10])) { - _PyArg_BadArgument("replace", 11, "tuple", args[10]); + _PyArg_BadArgument("replace", "argument 'co_varnames'", "tuple", args[10]); goto exit; } co_varnames = args[10]; @@ -198,7 +198,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } if (args[11]) { if (!PyTuple_Check(args[11])) { - _PyArg_BadArgument("replace", 12, "tuple", args[11]); + _PyArg_BadArgument("replace", "argument 'co_freevars'", "tuple", args[11]); goto exit; } co_freevars = args[11]; @@ -208,7 +208,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } if (args[12]) { if (!PyTuple_Check(args[12])) { - _PyArg_BadArgument("replace", 13, "tuple", args[12]); + _PyArg_BadArgument("replace", "argument 'co_cellvars'", "tuple", args[12]); goto exit; } co_cellvars = args[12]; @@ -218,7 +218,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } if (args[13]) { if (!PyUnicode_Check(args[13])) { - _PyArg_BadArgument("replace", 14, "str", args[13]); + _PyArg_BadArgument("replace", "argument 'co_filename'", "str", args[13]); goto exit; } if (PyUnicode_READY(args[13]) == -1) { @@ -231,7 +231,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } if (args[14]) { if (!PyUnicode_Check(args[14])) { - _PyArg_BadArgument("replace", 15, "str", args[14]); + _PyArg_BadArgument("replace", "argument 'co_name'", "str", args[14]); goto exit; } if (PyUnicode_READY(args[14]) == -1) { @@ -243,7 +243,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (!PyBytes_Check(args[15])) { - _PyArg_BadArgument("replace", 16, "bytes", args[15]); + _PyArg_BadArgument("replace", "argument 'co_lnotab'", "bytes", args[15]); goto exit; } co_lnotab = (PyBytesObject *)args[15]; @@ -253,4 +253,4 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje exit: return return_value; } -/*[clinic end generated code: output=624ab6f2ea8f0ea4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fade581d6313a0c2 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/dictobject.c.h b/Objects/clinic/dictobject.c.h index b87244d87348b9..8d5493330835e8 100644 --- a/Objects/clinic/dictobject.c.h +++ b/Objects/clinic/dictobject.c.h @@ -116,42 +116,6 @@ dict_setdefault(PyDictObject *self, PyObject *const *args, Py_ssize_t nargs) return return_value; } -PyDoc_STRVAR(dict_pop__doc__, -"pop($self, key, default=None, /)\n" -"--\n" -"\n" -"Remove specified key and return the corresponding value.\n" -"\n" -"If key is not found, default is returned if given, otherwise KeyError is raised"); - -#define DICT_POP_METHODDEF \ - {"pop", (PyCFunction)(void(*)(void))dict_pop, METH_FASTCALL, dict_pop__doc__}, - -static PyObject * -dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value); - -static PyObject * -dict_pop(PyDictObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *key; - PyObject *default_value = NULL; - - if (!_PyArg_CheckPositional("pop", nargs, 1, 2)) { - goto exit; - } - key = args[0]; - if (nargs < 2) { - goto skip_optional; - } - default_value = args[1]; -skip_optional: - return_value = dict_pop_impl(self, key, default_value); - -exit: - return return_value; -} - PyDoc_STRVAR(dict_popitem__doc__, "popitem($self, /)\n" "--\n" @@ -190,4 +154,4 @@ dict___reversed__(PyDictObject *self, PyObject *Py_UNUSED(ignored)) { return dict___reversed___impl(self); } -/*[clinic end generated code: output=0fd5cafc61a51d3c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=676532dcc941d399 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/floatobject.c.h b/Objects/clinic/floatobject.c.h index 4251d63c247b9f..b684ba0ef27aaf 100644 --- a/Objects/clinic/floatobject.c.h +++ b/Objects/clinic/floatobject.c.h @@ -56,7 +56,7 @@ static PyObject * float___round__(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *o_ndigits = NULL; + PyObject *o_ndigits = Py_None; if (!_PyArg_CheckPositional("__round__", nargs, 0, 1)) { goto exit; @@ -235,7 +235,7 @@ float___getformat__(PyTypeObject *type, PyObject *arg) const char *typestr; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("__getformat__", 0, "str", arg); + _PyArg_BadArgument("__getformat__", "argument", "str", arg); goto exit; } Py_ssize_t typestr_length; @@ -289,7 +289,7 @@ float___set_format__(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("__set_format__", 1, "str", args[0]); + _PyArg_BadArgument("__set_format__", "argument 1", "str", args[0]); goto exit; } Py_ssize_t typestr_length; @@ -302,7 +302,7 @@ float___set_format__(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs goto exit; } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("__set_format__", 2, "str", args[1]); + _PyArg_BadArgument("__set_format__", "argument 2", "str", args[1]); goto exit; } Py_ssize_t fmt_length; @@ -339,7 +339,7 @@ float___format__(PyObject *self, PyObject *arg) PyObject *format_spec; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("__format__", 0, "str", arg); + _PyArg_BadArgument("__format__", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -351,4 +351,4 @@ float___format__(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=c183029d87dd41fa input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1676433b9f04fbc9 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/funcobject.c.h b/Objects/clinic/funcobject.c.h index 929797bfb02d1a..17fb13fe085af3 100644 --- a/Objects/clinic/funcobject.c.h +++ b/Objects/clinic/funcobject.c.h @@ -44,12 +44,12 @@ func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } if (!PyObject_TypeCheck(fastargs[0], &PyCode_Type)) { - _PyArg_BadArgument("function", 1, (&PyCode_Type)->tp_name, fastargs[0]); + _PyArg_BadArgument("function", "argument 'code'", (&PyCode_Type)->tp_name, fastargs[0]); goto exit; } code = (PyCodeObject *)fastargs[0]; if (!PyDict_Check(fastargs[1])) { - _PyArg_BadArgument("function", 2, "dict", fastargs[1]); + _PyArg_BadArgument("function", "argument 'globals'", "dict", fastargs[1]); goto exit; } globals = fastargs[1]; @@ -75,4 +75,4 @@ func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=1d01072cd5620d7e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3d96afa3396e5c82 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h index 453edba481dfb5..27e8dfe935b6e1 100644 --- a/Objects/clinic/longobject.c.h +++ b/Objects/clinic/longobject.c.h @@ -74,7 +74,7 @@ int___format__(PyObject *self, PyObject *arg) PyObject *format_spec; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("__format__", 0, "str", arg); + _PyArg_BadArgument("__format__", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -227,7 +227,7 @@ int_to_bytes(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject * length = ival; } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("to_bytes", 2, "str", args[1]); + _PyArg_BadArgument("to_bytes", "argument 'byteorder'", "str", args[1]); goto exit; } if (PyUnicode_READY(args[1]) == -1) { @@ -293,7 +293,7 @@ int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyOb } bytes_obj = args[0]; if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("from_bytes", 2, "str", args[1]); + _PyArg_BadArgument("from_bytes", "argument 'byteorder'", "str", args[1]); goto exit; } if (PyUnicode_READY(args[1]) == -1) { @@ -313,4 +313,4 @@ int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyOb exit: return return_value; } -/*[clinic end generated code: output=709503897c55bca1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=77bc3b2615822cb8 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/memoryobject.c.h b/Objects/clinic/memoryobject.c.h index 64fce10acb5c5f..75ac2011261fa0 100644 --- a/Objects/clinic/memoryobject.c.h +++ b/Objects/clinic/memoryobject.c.h @@ -3,7 +3,7 @@ preserve [clinic start generated code]*/ PyDoc_STRVAR(memoryview_hex__doc__, -"hex($self, /, sep=None, bytes_per_sep=1)\n" +"hex($self, /, sep=, bytes_per_sep=1)\n" "--\n" "\n" "Return the data in the buffer as a str of hexadecimal numbers.\n" @@ -71,4 +71,4 @@ memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs exit: return return_value; } -/*[clinic end generated code: output=5e44e2bcf01057b5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ee265a73f68b0077 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/moduleobject.c.h b/Objects/clinic/moduleobject.c.h index 512edee72feaa2..c1534eaee25886 100644 --- a/Objects/clinic/moduleobject.c.h +++ b/Objects/clinic/moduleobject.c.h @@ -31,7 +31,7 @@ module___init__(PyObject *self, PyObject *args, PyObject *kwargs) goto exit; } if (!PyUnicode_Check(fastargs[0])) { - _PyArg_BadArgument("module", 1, "str", fastargs[0]); + _PyArg_BadArgument("module", "argument 'name'", "str", fastargs[0]); goto exit; } if (PyUnicode_READY(fastargs[0]) == -1) { @@ -48,4 +48,4 @@ module___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=d7b7ca1237597b08 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=680276bc3a496d7a input=a9049054013a1b77]*/ diff --git a/Objects/clinic/typeobject.c.h b/Objects/clinic/typeobject.c.h index fbe1261fb5a062..357eb44b12b8a1 100644 --- a/Objects/clinic/typeobject.c.h +++ b/Objects/clinic/typeobject.c.h @@ -200,7 +200,7 @@ object___format__(PyObject *self, PyObject *arg) PyObject *format_spec; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("__format__", 0, "str", arg); + _PyArg_BadArgument("__format__", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -248,4 +248,4 @@ object___dir__(PyObject *self, PyObject *Py_UNUSED(ignored)) { return object___dir___impl(self); } -/*[clinic end generated code: output=ea5734413064fa7e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7a6d272d282308f3 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/unicodeobject.c.h b/Objects/clinic/unicodeobject.c.h index 647507dea61a48..0d134064bab091 100644 --- a/Objects/clinic/unicodeobject.c.h +++ b/Objects/clinic/unicodeobject.c.h @@ -157,7 +157,7 @@ unicode_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject } if (args[0]) { if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("encode", 1, "str", args[0]); + _PyArg_BadArgument("encode", "argument 'encoding'", "str", args[0]); goto exit; } Py_ssize_t encoding_length; @@ -174,7 +174,7 @@ unicode_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject } } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("encode", 2, "str", args[1]); + _PyArg_BadArgument("encode", "argument 'errors'", "str", args[1]); goto exit; } Py_ssize_t errors_length; @@ -582,7 +582,7 @@ PyDoc_STRVAR(unicode_strip__doc__, "strip($self, chars=None, /)\n" "--\n" "\n" -"Return a copy of the string with leading and trailing whitespace remove.\n" +"Return a copy of the string with leading and trailing whitespace removed.\n" "\n" "If chars is given and not None, remove characters in chars instead."); @@ -630,7 +630,7 @@ static PyObject * unicode_lstrip(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *chars = NULL; + PyObject *chars = Py_None; if (!_PyArg_CheckPositional("lstrip", nargs, 0, 1)) { goto exit; @@ -664,7 +664,7 @@ static PyObject * unicode_rstrip(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *chars = NULL; + PyObject *chars = Py_None; if (!_PyArg_CheckPositional("rstrip", nargs, 0, 1)) { goto exit; @@ -712,7 +712,7 @@ unicode_replace(PyObject *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("replace", 1, "str", args[0]); + _PyArg_BadArgument("replace", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -720,7 +720,7 @@ unicode_replace(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } old = args[0]; if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("replace", 2, "str", args[1]); + _PyArg_BadArgument("replace", "argument 2", "str", args[1]); goto exit; } if (PyUnicode_READY(args[1]) == -1) { @@ -1045,7 +1045,7 @@ unicode_swapcase(PyObject *self, PyObject *Py_UNUSED(ignored)) } PyDoc_STRVAR(unicode_maketrans__doc__, -"maketrans(x, y=None, z=None, /)\n" +"maketrans(x, y=, z=, /)\n" "--\n" "\n" "Return a translation table usable for str.translate().\n" @@ -1080,7 +1080,7 @@ unicode_maketrans(void *null, PyObject *const *args, Py_ssize_t nargs) goto skip_optional; } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("maketrans", 2, "str", args[1]); + _PyArg_BadArgument("maketrans", "argument 2", "str", args[1]); goto exit; } if (PyUnicode_READY(args[1]) == -1) { @@ -1091,7 +1091,7 @@ unicode_maketrans(void *null, PyObject *const *args, Py_ssize_t nargs) goto skip_optional; } if (!PyUnicode_Check(args[2])) { - _PyArg_BadArgument("maketrans", 3, "str", args[2]); + _PyArg_BadArgument("maketrans", "argument 3", "str", args[2]); goto exit; } if (PyUnicode_READY(args[2]) == -1) { @@ -1202,7 +1202,7 @@ unicode___format__(PyObject *self, PyObject *arg) PyObject *format_spec; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("__format__", 0, "str", arg); + _PyArg_BadArgument("__format__", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -1232,4 +1232,4 @@ unicode_sizeof(PyObject *self, PyObject *Py_UNUSED(ignored)) { return unicode_sizeof_impl(self); } -/*[clinic end generated code: output=d1541724cb4a0070 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e4ed33400979c7e8 input=a9049054013a1b77]*/ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 63ce4793597a13..39bf6fc6f228e7 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -102,14 +102,13 @@ intern_string_constants(PyObject *tuple) return modified; } - PyCodeObject * -PyCode_New(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) +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) { PyCodeObject *co; Py_ssize_t *cell2arg = NULL; @@ -243,6 +242,20 @@ PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount, return co; } +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) +{ + return PyCode_NewWithPosOnlyArgs(argcount, 0, kwonlyargcount, nlocals, + stacksize, flags, code, consts, names, + varnames, freevars, cellvars, filename, + name, firstlineno, lnotab); +} + int _PyCode_InitOpcache(PyCodeObject *co) { @@ -282,7 +295,7 @@ _PyCode_InitOpcache(PyCodeObject *co) co->co_opcache = NULL; } - co->co_opcache_size = opts; + co->co_opcache_size = (unsigned char)opts; return 0; } @@ -311,7 +324,8 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) if (filename_ob == NULL) goto failed; - result = PyCode_New(0, /* argcount */ + result = PyCode_NewWithPosOnlyArgs( + 0, /* argcount */ 0, /* posonlyargcount */ 0, /* kwonlyargcount */ 0, /* nlocals */ @@ -492,12 +506,14 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (ourcellvars == NULL) goto cleanup; - co = (PyObject *)PyCode_New(argcount, posonlyargcount, kwonlyargcount, - nlocals, stacksize, flags, - code, consts, ournames, ourvarnames, - ourfreevars, ourcellvars, filename, - name, firstlineno, lnotab); - cleanup: + co = (PyObject *)PyCode_NewWithPosOnlyArgs(argcount, posonlyargcount, + kwonlyargcount, + nlocals, stacksize, flags, + code, consts, ournames, + ourvarnames, ourfreevars, + ourcellvars, filename, + name, firstlineno, lnotab); + cleanup: Py_XDECREF(ournames); Py_XDECREF(ourvarnames); Py_XDECREF(ourfreevars); @@ -625,7 +641,7 @@ code_replace_impl(PyCodeObject *self, int co_argcount, #undef CHECK_INT_ARG - return (PyObject *)PyCode_New( + return (PyObject *)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, diff --git a/Objects/complexobject.c b/Objects/complexobject.c index f78c0fdf78def4..a49da4018411e7 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -55,6 +55,10 @@ _Py_c_prod(Py_complex a, Py_complex b) return r; } +/* Avoid bad optimization on Windows ARM64 until the compiler is fixed */ +#ifdef _M_ARM64 +#pragma optimize("", off) +#endif Py_complex _Py_c_quot(Py_complex a, Py_complex b) { @@ -112,6 +116,9 @@ _Py_c_quot(Py_complex a, Py_complex b) } return r; } +#ifdef _M_ARM64 +#pragma optimize("", on) +#endif Py_complex _Py_c_pow(Py_complex a, Py_complex b) diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 6c95a8726c4202..119be35db08d8a 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -226,80 +226,199 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) return -1; } -static PyObject * -methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs) -{ - Py_ssize_t nargs; - PyObject *self, *result; - /* Make sure that the first argument is acceptable as 'self' */ - assert(PyTuple_Check(args)); - nargs = PyTuple_GET_SIZE(args); +/* Vectorcall functions for each of the PyMethodDescr calling conventions. + * + * First, common helpers + */ +static const char * +get_name(PyObject *func) { + assert(PyObject_TypeCheck(func, &PyMethodDescr_Type)); + return ((PyMethodDescrObject *)func)->d_method->ml_name; +} + +typedef void (*funcptr)(void); + +static inline int +method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + assert(!PyErr_Occurred()); + assert(PyObject_TypeCheck(func, &PyMethodDescr_Type)); if (nargs < 1) { PyErr_Format(PyExc_TypeError, - "descriptor '%V' of '%.100s' " + "descriptor '%.200s' of '%.100s' " "object needs an argument", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name); - return NULL; + get_name(func), PyDescr_TYPE(func)->tp_name); + return -1; } - self = PyTuple_GET_ITEM(args, 0); + PyObject *self = args[0]; if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), - (PyObject *)PyDescr_TYPE(descr))) { + (PyObject *)PyDescr_TYPE(func))) + { PyErr_Format(PyExc_TypeError, - "descriptor '%V' for '%.100s' objects " + "descriptor '%.200s' for '%.100s' objects " "doesn't apply to a '%.100s' object", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name, - self->ob_type->tp_name); + get_name(func), PyDescr_TYPE(func)->tp_name, + Py_TYPE(self)->tp_name); + return -1; + } + if (kwnames && PyTuple_GET_SIZE(kwnames)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", get_name(func)); + return -1; + } + return 0; +} + +static inline funcptr +method_enter_call(PyObject *func) +{ + if (Py_EnterRecursiveCall(" while calling a Python object")) { return NULL; } + return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth; +} - result = _PyMethodDef_RawFastCallDict(descr->d_method, self, - &_PyTuple_ITEMS(args)[1], nargs - 1, - kwargs); - result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL); +/* Now the actual vectorcall functions */ +static PyObject * +method_vectorcall_VARARGS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, kwnames)) { + return NULL; + } + PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1); + if (argstuple == NULL) { + return NULL; + } + PyCFunction meth = (PyCFunction)method_enter_call(func); + if (meth == NULL) { + Py_DECREF(argstuple); + return NULL; + } + PyObject *result = meth(args[0], argstuple); + Py_DECREF(argstuple); + Py_LeaveRecursiveCall(); return result; } -// same to methoddescr_call(), but use FASTCALL convention. -PyObject * -_PyMethodDescr_Vectorcall(PyObject *descrobj, - PyObject *const *args, size_t nargsf, - PyObject *kwnames) +static PyObject * +method_vectorcall_VARARGS_KEYWORDS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { - assert(Py_TYPE(descrobj) == &PyMethodDescr_Type); - PyMethodDescrObject *descr = (PyMethodDescrObject *)descrobj; - PyObject *self, *result; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, NULL)) { + return NULL; + } + PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1); + if (argstuple == NULL) { + return NULL; + } + PyObject *result = NULL; + /* Create a temporary dict for keyword arguments */ + PyObject *kwdict = NULL; + if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) > 0) { + kwdict = _PyStack_AsDict(args + nargs, kwnames); + if (kwdict == NULL) { + goto exit; + } + } + PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords) + method_enter_call(func); + if (meth == NULL) { + goto exit; + } + result = meth(args[0], argstuple, kwdict); + Py_LeaveRecursiveCall(); +exit: + Py_DECREF(argstuple); + Py_XDECREF(kwdict); + return result; +} +static PyObject * +method_vectorcall_FASTCALL( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - /* Make sure that the first argument is acceptable as 'self' */ - if (nargs < 1) { - PyErr_Format(PyExc_TypeError, - "descriptor '%V' of '%.100s' " - "object needs an argument", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name); + if (method_check_args(func, args, nargs, kwnames)) { return NULL; } - self = args[0]; - if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), - (PyObject *)PyDescr_TYPE(descr))) { + _PyCFunctionFast meth = (_PyCFunctionFast) + method_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], args+1, nargs-1); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +method_vectorcall_FASTCALL_KEYWORDS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, NULL)) { + return NULL; + } + _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords) + method_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], args+1, nargs-1, kwnames); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +method_vectorcall_NOARGS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, kwnames)) { + return NULL; + } + if (nargs != 1) { PyErr_Format(PyExc_TypeError, - "descriptor '%V' for '%.100s' objects " - "doesn't apply to a '%.100s' object", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name, - self->ob_type->tp_name); + "%.200s() takes no arguments (%zd given)", get_name(func), nargs-1); return NULL; } + PyCFunction meth = (PyCFunction)method_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], NULL); + Py_LeaveRecursiveCall(); + return result; +} - result = _PyMethodDef_RawFastCallKeywords(descr->d_method, self, - args+1, nargs-1, kwnames); - result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL); +static PyObject * +method_vectorcall_O( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, kwnames)) { + return NULL; + } + if (nargs != 2) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%zd given)", + get_name(func), nargs-1); + return NULL; + } + PyCFunction meth = (PyCFunction)method_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], args[1]); + Py_LeaveRecursiveCall(); return result; } + static PyObject * classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) @@ -552,7 +671,7 @@ PyTypeObject PyMethodDescr_Type = { 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ - (ternaryfunc)methoddescr_call, /* tp_call */ + PyVectorcall_Call, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ @@ -750,13 +869,40 @@ descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) PyObject * PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) { + /* Figure out correct vectorcall function to use */ + vectorcallfunc vectorcall; + switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS)) + { + case METH_VARARGS: + vectorcall = method_vectorcall_VARARGS; + break; + case METH_VARARGS | METH_KEYWORDS: + vectorcall = method_vectorcall_VARARGS_KEYWORDS; + break; + case METH_FASTCALL: + vectorcall = method_vectorcall_FASTCALL; + break; + case METH_FASTCALL | METH_KEYWORDS: + vectorcall = method_vectorcall_FASTCALL_KEYWORDS; + break; + case METH_NOARGS: + vectorcall = method_vectorcall_NOARGS; + break; + case METH_O: + vectorcall = method_vectorcall_O; + break; + default: + PyErr_SetString(PyExc_SystemError, "bad call flags"); + return NULL; + } + PyMethodDescrObject *descr; descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type, type, method->ml_name); if (descr != NULL) { descr->d_method = method; - descr->vectorcall = _PyMethodDescr_Vectorcall; + descr->vectorcall = vectorcall; } return (PyObject *)descr; } @@ -1476,29 +1622,25 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset, /* 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 = _PyObject_GetAttrId(fget, &PyId___doc__); - if (get_doc) { - if (Py_TYPE(self) == &PyProperty_Type) { - Py_XSETREF(self->prop_doc, get_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. */ - int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc); - Py_DECREF(get_doc); - if (err < 0) - return -1; - } - self->getter_doc = 1; + PyObject *get_doc; + int rc = _PyObject_LookupAttrId(fget, &PyId___doc__, &get_doc); + if (rc <= 0) { + return rc; } - else if (PyErr_ExceptionMatches(PyExc_Exception)) { - PyErr_Clear(); + if (Py_TYPE(self) == &PyProperty_Type) { + Py_XSETREF(self->prop_doc, get_doc); } else { - return -1; + /* 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; } + self->getter_doc = 1; } return 0; diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 0cc14437500699..76f4fefe0979ff 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -39,7 +39,7 @@ 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. It's size is USABLE_FRACTION(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. NOTE: Since negative value is used for DKIX_EMPTY and DKIX_DUMMY, type of @@ -459,23 +459,26 @@ static PyObject *empty_values[1] = { NULL }; int _PyDict_CheckConsistency(PyObject *op, int check_content) { -#ifndef NDEBUG - _PyObject_ASSERT(op, PyDict_Check(op)); +#define CHECK(expr) \ + do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0) + + assert(op != NULL); + CHECK(PyDict_Check(op)); PyDictObject *mp = (PyDictObject *)op; PyDictKeysObject *keys = mp->ma_keys; int splitted = _PyDict_HasSplitTable(mp); Py_ssize_t usable = USABLE_FRACTION(keys->dk_size); - _PyObject_ASSERT(op, 0 <= mp->ma_used && mp->ma_used <= usable); - _PyObject_ASSERT(op, IS_POWER_OF_2(keys->dk_size)); - _PyObject_ASSERT(op, 0 <= keys->dk_usable && keys->dk_usable <= usable); - _PyObject_ASSERT(op, 0 <= keys->dk_nentries && keys->dk_nentries <= usable); - _PyObject_ASSERT(op, keys->dk_usable + keys->dk_nentries <= usable); + CHECK(0 <= mp->ma_used && mp->ma_used <= usable); + CHECK(IS_POWER_OF_2(keys->dk_size)); + CHECK(0 <= keys->dk_usable && keys->dk_usable <= usable); + CHECK(0 <= keys->dk_nentries && keys->dk_nentries <= usable); + CHECK(keys->dk_usable + keys->dk_nentries <= usable); if (!splitted) { /* combined table */ - _PyObject_ASSERT(op, keys->dk_refcnt == 1); + CHECK(keys->dk_refcnt == 1); } if (check_content) { @@ -484,7 +487,7 @@ _PyDict_CheckConsistency(PyObject *op, int check_content) for (i=0; i < keys->dk_size; i++) { Py_ssize_t ix = dictkeys_get_index(keys, i); - _PyObject_ASSERT(op, DKIX_DUMMY <= ix && ix <= usable); + CHECK(DKIX_DUMMY <= ix && ix <= usable); } for (i=0; i < usable; i++) { @@ -494,32 +497,33 @@ _PyDict_CheckConsistency(PyObject *op, int check_content) if (key != NULL) { if (PyUnicode_CheckExact(key)) { Py_hash_t hash = ((PyASCIIObject *)key)->hash; - _PyObject_ASSERT(op, hash != -1); - _PyObject_ASSERT(op, entry->me_hash == hash); + CHECK(hash != -1); + CHECK(entry->me_hash == hash); } else { /* test_dict fails if PyObject_Hash() is called again */ - _PyObject_ASSERT(op, entry->me_hash != -1); + CHECK(entry->me_hash != -1); } if (!splitted) { - _PyObject_ASSERT(op, entry->me_value != NULL); + CHECK(entry->me_value != NULL); } } if (splitted) { - _PyObject_ASSERT(op, entry->me_value == NULL); + CHECK(entry->me_value == NULL); } } if (splitted) { /* splitted table */ for (i=0; i < mp->ma_used; i++) { - _PyObject_ASSERT(op, mp->ma_values[i] != NULL); + CHECK(mp->ma_values[i] != NULL); } } } -#endif return 1; + +#undef CHECK } @@ -1129,7 +1133,7 @@ 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)[0]; + PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys); dictkeys_set_index(mp->ma_keys, hashpos, 0); ep->me_key = key; ep->me_hash = hash; @@ -2987,23 +2991,37 @@ dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } -/*[clinic input] -dict.pop - - key: object - default: object = NULL - / - -Remove specified key and return the corresponding value. +/* +We don't use Argument Clinic for dict.pop because it doesn't support +custom signature for now. +*/ +PyDoc_STRVAR(dict_pop__doc__, +"D.pop(k[,d]) -> v, remove specified key and return the corresponding value.\n\ +If key is not found, d is returned if given, otherwise KeyError is raised"); -If key is not found, default is returned if given, otherwise KeyError is raised -[clinic start generated code]*/ +#define DICT_POP_METHODDEF \ + {"pop", (PyCFunction)(void(*)(void))dict_pop, METH_FASTCALL, dict_pop__doc__}, static PyObject * -dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value) -/*[clinic end generated code: output=3abb47b89f24c21c input=016f6a000e4e633b]*/ +dict_pop(PyDictObject *self, PyObject *const *args, Py_ssize_t nargs) { - return _PyDict_Pop((PyObject*)self, key, default_value); + PyObject *return_value = NULL; + PyObject *key; + PyObject *default_value = NULL; + + if (!_PyArg_CheckPositional("pop", nargs, 1, 2)) { + goto exit; + } + key = args[0]; + if (nargs < 2) { + goto skip_optional; + } + default_value = args[1]; +skip_optional: + return_value = _PyDict_Pop((PyObject*)self, key, default_value); + +exit: + return return_value; } /*[clinic input] @@ -3444,10 +3462,15 @@ dictiter_new(PyDictObject *dict, PyTypeObject *itertype) di->di_dict = dict; di->di_used = dict->ma_used; di->len = dict->ma_used; - if ((itertype == &PyDictRevIterKey_Type || + if (itertype == &PyDictRevIterKey_Type || itertype == &PyDictRevIterItem_Type || - itertype == &PyDictRevIterValue_Type) && dict->ma_used) { + itertype == &PyDictRevIterValue_Type) { + if (dict->ma_values) { + di->di_pos = dict->ma_used - 1; + } + else { di->di_pos = dict->ma_keys->dk_nentries - 1; + } } else { di->di_pos = 0; @@ -3817,22 +3840,21 @@ dictreviter_iternext(dictiterobject *di) PyDictKeysObject *k = d->ma_keys; PyObject *key, *value, *result; + if (i < 0) { + goto fail; + } if (d->ma_values) { - if (i < 0) { - goto fail; - } key = DK_ENTRIES(k)[i].me_key; value = d->ma_values[i]; assert (value != NULL); } else { PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i]; - while (i >= 0 && entry_ptr->me_value == NULL) { + while (entry_ptr->me_value == NULL) { + if (--i < 0) { + goto fail; + } entry_ptr--; - i--; - } - if (i < 0) { - goto fail; } key = entry_ptr->me_key; value = entry_ptr->me_value; diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 568d4959e3a0af..38723d93653c30 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1521,13 +1521,6 @@ MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError, "Improper indentation."); -/* - * TargetScopeError extends SyntaxError - */ -MiddlingExtendsException(PyExc_SyntaxError, TargetScopeError, SyntaxError, - "Improper scope target."); - - /* * TabError extends IndentationError */ @@ -2539,7 +2532,6 @@ _PyExc_Init(void) PRE_INIT(AttributeError); PRE_INIT(SyntaxError); PRE_INIT(IndentationError); - PRE_INIT(TargetScopeError); PRE_INIT(TabError); PRE_INIT(LookupError); PRE_INIT(IndexError); @@ -2680,7 +2672,6 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod) POST_INIT(AttributeError); POST_INIT(SyntaxError); POST_INIT(IndentationError); - POST_INIT(TargetScopeError); POST_INIT(TabError); POST_INIT(LookupError); POST_INIT(IndexError); diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 3791241e5c7c3d..dd42d516898a59 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -185,8 +185,10 @@ PyObject_AsFileDescriptor(PyObject *o) if (PyLong_Check(o)) { fd = _PyLong_AsInt(o); } - else if ((meth = _PyObject_GetAttrId(o, &PyId_fileno)) != NULL) - { + else if (_PyObject_LookupAttrId(o, &PyId_fileno, &meth) < 0) { + return -1; + } + else if (meth != NULL) { PyObject *fno = _PyObject_CallNoArg(meth); Py_DECREF(meth); if (fno == NULL) diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 15cbe5c9d8bae5..1cb8ff795fb87f 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -43,7 +43,7 @@ static PyTypeObject FloatInfoType; PyDoc_STRVAR(floatinfo__doc__, "sys.float_info\n\ \n\ -A structseq holding information about the float type. It contains low level\n\ +A named tuple holding information about the float type. It contains low level\n\ information about the precision and internal representation. Please study\n\ your system's :file:`float.h` for more information."); @@ -1042,7 +1042,7 @@ double_round(double x, int ndigits) { /*[clinic input] float.__round__ - ndigits as o_ndigits: object = NULL + ndigits as o_ndigits: object = None / Return the Integral closest to x, rounding half toward even. @@ -1052,13 +1052,13 @@ When an argument is passed, work like built-in round(x, ndigits). static PyObject * float___round___impl(PyObject *self, PyObject *o_ndigits) -/*[clinic end generated code: output=374c36aaa0f13980 input=1ca2316b510293b8]*/ +/*[clinic end generated code: output=374c36aaa0f13980 input=fc0fe25924fbc9ed]*/ { double x, rounded; Py_ssize_t ndigits; x = PyFloat_AsDouble(self); - if (o_ndigits == NULL || o_ndigits == Py_None) { + if (o_ndigits == Py_None) { /* single-argument round or with None ndigits: * round to nearest integer */ rounded = round(x); diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 5deb9858ce86c9..a796a59eee9e40 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -233,6 +233,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore * the 'finally' blocks. */ memset(blockstack, '\0', sizeof(blockstack)); blockstack_top = 0; + unsigned char prevop = NOP; for (addr = 0; addr < code_len; addr += sizeof(_Py_CODEUNIT)) { unsigned char op = code[addr]; switch (op) { @@ -259,17 +260,24 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore "can't jump into the middle of a block"); return -1; } + int in_for_loop = op == FOR_ITER || code[target_addr] == END_ASYNC_FOR; if (first_in && !second_in) { - if (op != FOR_ITER && code[target_addr] != END_ASYNC_FOR) { - delta_iblock++; + if (!delta_iblock) { + if (in_for_loop) { + /* Pop the iterators of any 'for' and 'async for' loop + * we're jumping out of. */ + delta++; + } + else if (prevop == LOAD_CONST) { + /* Pops None pushed before SETUP_FINALLY. */ + delta++; + } } - else if (!delta_iblock) { - /* Pop the iterators of any 'for' and 'async for' loop - * we're jumping out of. */ - delta++; + if (!in_for_loop) { + delta_iblock++; } } - if (op != FOR_ITER && code[target_addr] != END_ASYNC_FOR) { + if (!in_for_loop) { blockstack[blockstack_top++] = target_addr; } break; @@ -293,6 +301,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore break; } } + prevop = op; } /* Verify that the blockstack tracking code didn't get lost. */ diff --git a/Objects/genobject.c b/Objects/genobject.c index 2d9a2860a3d273..6285219bb2d714 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1342,7 +1342,8 @@ static PyGetSetDef async_gen_getsetlist[] = { static PyMemberDef async_gen_memberlist[] = { {"ag_frame", T_OBJECT, offsetof(PyAsyncGenObject, ag_frame), READONLY}, - {"ag_running", T_BOOL, offsetof(PyAsyncGenObject, ag_running), READONLY}, + {"ag_running", T_BOOL, offsetof(PyAsyncGenObject, ag_running_async), + READONLY}, {"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code), READONLY}, {NULL} /* Sentinel */ }; @@ -1436,6 +1437,7 @@ PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname) o->ag_finalizer = NULL; o->ag_closed = 0; o->ag_hooks_inited = 0; + o->ag_running_async = 0; return (PyObject*)o; } @@ -1483,6 +1485,7 @@ async_gen_unwrap_value(PyAsyncGenObject *gen, PyObject *result) gen->ag_closed = 1; } + gen->ag_running_async = 0; return NULL; } @@ -1490,6 +1493,7 @@ async_gen_unwrap_value(PyAsyncGenObject *gen, PyObject *result) /* async yield */ _PyGen_SetStopIterationValue(((_PyAsyncGenWrappedValue*)result)->agw_val); Py_DECREF(result); + gen->ag_running_async = 0; return NULL; } @@ -1534,12 +1538,20 @@ async_gen_asend_send(PyAsyncGenASend *o, PyObject *arg) } if (o->ags_state == AWAITABLE_STATE_INIT) { + if (o->ags_gen->ag_running_async) { + PyErr_SetString( + PyExc_RuntimeError, + "anext(): asynchronous generator is already running"); + return NULL; + } + if (arg == NULL || arg == Py_None) { arg = o->ags_sendval; } o->ags_state = AWAITABLE_STATE_ITER; } + o->ags_gen->ag_running_async = 1; result = gen_send_ex((PyGenObject*)o->ags_gen, arg, 0, 0); result = async_gen_unwrap_value(o->ags_gen, result); @@ -1803,8 +1815,23 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) } if (o->agt_state == AWAITABLE_STATE_INIT) { + if (o->agt_gen->ag_running_async) { + if (o->agt_args == NULL) { + PyErr_SetString( + PyExc_RuntimeError, + "aclose(): asynchronous generator is already running"); + } + else { + PyErr_SetString( + PyExc_RuntimeError, + "athrow(): asynchronous generator is already running"); + } + return NULL; + } + if (o->agt_gen->ag_closed) { - PyErr_SetNone(PyExc_StopIteration); + o->agt_state = AWAITABLE_STATE_CLOSED; + PyErr_SetNone(PyExc_StopAsyncIteration); return NULL; } @@ -1814,6 +1841,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) } o->agt_state = AWAITABLE_STATE_ITER; + o->agt_gen->ag_running_async = 1; if (o->agt_args == NULL) { /* aclose() mode */ @@ -1859,6 +1887,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) /* aclose() mode */ if (retval) { if (_PyAsyncGenWrappedValue_CheckExact(retval)) { + o->agt_gen->ag_running_async = 0; Py_DECREF(retval); goto yield_close; } @@ -1872,11 +1901,13 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) } yield_close: + o->agt_gen->ag_running_async = 0; PyErr_SetString( PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; check_error: + o->agt_gen->ag_running_async = 0; if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) || PyErr_ExceptionMatches(PyExc_GeneratorExit)) { @@ -1900,11 +1931,6 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) { PyObject *retval; - if (o->agt_state == AWAITABLE_STATE_INIT) { - PyErr_SetString(PyExc_RuntimeError, NON_INIT_CORO_MSG); - return NULL; - } - if (o->agt_state == AWAITABLE_STATE_CLOSED) { PyErr_SetNone(PyExc_StopIteration); return NULL; @@ -1916,6 +1942,7 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) } else { /* aclose() mode */ if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) { + o->agt_gen->ag_running_async = 0; Py_DECREF(retval); PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; diff --git a/Objects/interpreteridobject.c b/Objects/interpreteridobject.c index 0a1dfa25795fa9..94f5dd709bbda0 100644 --- a/Objects/interpreteridobject.c +++ b/Objects/interpreteridobject.c @@ -5,38 +5,6 @@ #include "interpreteridobject.h" -int64_t -_Py_CoerceID(PyObject *orig) -{ - PyObject *pyid = PyNumber_Long(orig); - if (pyid == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_Format(PyExc_TypeError, - "'id' must be a non-negative int, got %R", orig); - } - else { - PyErr_Format(PyExc_ValueError, - "'id' must be a non-negative int, got %R", orig); - } - return -1; - } - int64_t id = PyLong_AsLongLong(pyid); - Py_DECREF(pyid); - if (id == -1 && PyErr_Occurred() != NULL) { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) { - PyErr_Format(PyExc_ValueError, - "'id' must be a non-negative int, got %R", orig); - } - return -1; - } - if (id < 0) { - PyErr_Format(PyExc_ValueError, - "'id' must be a non-negative int, got %R", orig); - return -1; - } - return id; -} - typedef struct interpid { PyObject_HEAD int64_t id; @@ -67,30 +35,46 @@ newinterpid(PyTypeObject *cls, int64_t id, int force) return self; } +static int +interp_id_converter(PyObject *arg, void *ptr) +{ + int64_t id; + if (PyObject_TypeCheck(arg, &_PyInterpreterID_Type)) { + id = ((interpid *)arg)->id; + } + else if (PyIndex_Check(arg)) { + id = PyLong_AsLongLong(arg); + if (id == -1 && PyErr_Occurred()) { + return 0; + } + if (id < 0) { + PyErr_Format(PyExc_ValueError, + "interpreter ID must be a non-negative int, got %R", arg); + return 0; + } + } + else { + PyErr_Format(PyExc_TypeError, + "interpreter ID must be an int, got %.100s", + arg->ob_type->tp_name); + return 0; + } + *(int64_t *)ptr = id; + return 1; +} + static PyObject * interpid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"id", "force", NULL}; - PyObject *idobj; + int64_t id; int force = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O|$p:InterpreterID.__init__", kwlist, - &idobj, &force)) { + "O&|$p:InterpreterID.__init__", kwlist, + interp_id_converter, &id, &force)) { return NULL; } - // Coerce and check the ID. - int64_t id; - if (PyObject_TypeCheck(idobj, &_PyInterpreterID_Type)) { - id = ((interpid *)idobj)->id; - } - else { - id = _Py_CoerceID(idobj); - if (id < 0) { - return NULL; - } - } - return (PyObject *)newinterpid(cls, id, force); } @@ -202,23 +186,26 @@ interpid_richcompare(PyObject *self, PyObject *other, int op) interpid *otherid = (interpid *)other; equal = (id->id == otherid->id); } - else { - other = PyNumber_Long(other); - if (other == NULL) { - PyErr_Clear(); - Py_RETURN_NOTIMPLEMENTED; - } - int64_t otherid = PyLong_AsLongLong(other); - Py_DECREF(other); - if (otherid == -1 && PyErr_Occurred() != NULL) { + else if (PyLong_CheckExact(other)) { + /* Fast path */ + int overflow; + long long otherid = PyLong_AsLongLongAndOverflow(other, &overflow); + if (otherid == -1 && PyErr_Occurred()) { return NULL; } - if (otherid < 0) { - equal = 0; - } - else { - equal = (id->id == otherid); + equal = !overflow && (otherid >= 0) && (id->id == otherid); + } + else if (PyNumber_Check(other)) { + PyObject *pyid = PyLong_FromLongLong(id->id); + if (pyid == NULL) { + return NULL; } + PyObject *res = PyObject_RichCompare(pyid, other, op); + Py_DECREF(pyid); + return res; + } + else { + Py_RETURN_NOTIMPLEMENTED; } if ((op == Py_EQ && equal) || (op == Py_NE && !equal)) { @@ -250,8 +237,7 @@ PyTypeObject _PyInterpreterID_Type = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ interpid_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -262,7 +248,7 @@ PyTypeObject _PyInterpreterID_Type = { 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ - &PyLong_Type, /* tp_base */ + 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ @@ -294,15 +280,8 @@ PyInterpreterState * _PyInterpreterID_LookUp(PyObject *requested_id) { int64_t id; - if (PyObject_TypeCheck(requested_id, &_PyInterpreterID_Type)) { - id = ((interpid *)requested_id)->id; - } - else { - id = PyLong_AsLongLong(requested_id); - if (id == -1 && PyErr_Occurred() != NULL) { - return NULL; - } - assert(id <= INT64_MAX); + if (!interp_id_converter(requested_id, &id)) { + return NULL; } return _PyInterpreterState_LookUpID(id); } diff --git a/Objects/listsort.txt b/Objects/listsort.txt index 8c877515c72e88..43fe1574c32393 100644 --- a/Objects/listsort.txt +++ b/Objects/listsort.txt @@ -328,7 +328,7 @@ found is still high in the memory hierarchy. We also can't delay merging unmerged, and the stack has a fixed size. What turned out to be a good compromise maintains two invariants on the -stack entries, where A, B and C are the lengths of the three righmost not-yet +stack entries, where A, B and C are the lengths of the three rightmost not-yet merged slices: 1. A > B+C diff --git a/Objects/lnotab_notes.txt b/Objects/lnotab_notes.txt index 3dab2b98661695..71a297971828c0 100644 --- a/Objects/lnotab_notes.txt +++ b/Objects/lnotab_notes.txt @@ -3,7 +3,9 @@ All about co_lnotab, the line number table. Code objects store a field named co_lnotab. This is an array of unsigned bytes disguised as a Python bytes object. It is used to map bytecode offsets to source code line #s for tracebacks and to identify line number boundaries for -line tracing. +line tracing. Because of internals of the peephole optimizer, it's possible +for lnotab to contain bytecode offsets that are no longer valid (for example +if the optimizer removed the last line in a function). The array is conceptually a compressed list of (bytecode offset increment, line number increment) diff --git a/Objects/longobject.c b/Objects/longobject.c index a1103f697c7379..708934c51fe250 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1376,7 +1376,7 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv) if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); - return (unsigned long) -1; + return (unsigned long long) -1; } v = (PyLongObject *)vv; switch(Py_SIZE(v)) { @@ -1404,7 +1404,7 @@ PyLong_AsUnsignedLongLongMask(PyObject *op) if (op == NULL) { PyErr_BadInternalCall(); - return (unsigned long)-1; + return (unsigned long long)-1; } if (PyLong_Check(op)) { @@ -5771,7 +5771,7 @@ static PyTypeObject Int_InfoType; PyDoc_STRVAR(int_info__doc__, "sys.int_info\n\ \n\ -A struct sequence that holds information about Python's\n\ +A named tuple that holds information about Python's\n\ internal representation of integers. The attributes are read only."); static PyStructSequence_Field int_info_fields[] = { diff --git a/Objects/methodobject.c b/Objects/methodobject.c index c3bc0184796e40..3494f11d80fe75 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -19,6 +19,17 @@ static int numfree = 0; /* undefine macro trampoline to PyCFunction_NewEx */ #undef PyCFunction_New +/* Forward declarations */ +static PyObject * cfunction_vectorcall_FASTCALL( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * cfunction_vectorcall_NOARGS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * cfunction_vectorcall_O( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); + + PyObject * PyCFunction_New(PyMethodDef *ml, PyObject *self) { @@ -28,6 +39,33 @@ PyCFunction_New(PyMethodDef *ml, PyObject *self) PyObject * PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) { + /* Figure out correct vectorcall function to use */ + vectorcallfunc vectorcall; + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS)) + { + case METH_VARARGS: + case METH_VARARGS | METH_KEYWORDS: + /* For METH_VARARGS functions, it's more efficient to use tp_call + * instead of vectorcall. */ + vectorcall = NULL; + break; + case METH_FASTCALL: + vectorcall = cfunction_vectorcall_FASTCALL; + break; + case METH_FASTCALL | METH_KEYWORDS: + vectorcall = cfunction_vectorcall_FASTCALL_KEYWORDS; + break; + case METH_NOARGS: + vectorcall = cfunction_vectorcall_NOARGS; + break; + case METH_O: + vectorcall = cfunction_vectorcall_O; + break; + default: + PyErr_SetString(PyExc_SystemError, "bad call flags"); + return NULL; + } + PyCFunctionObject *op; op = free_list; if (op != NULL) { @@ -46,14 +84,7 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) op->m_self = self; Py_XINCREF(module); op->m_module = module; - if (ml->ml_flags & METH_VARARGS) { - /* For METH_VARARGS functions, it's more efficient to use tp_call - * instead of vectorcall. */ - op->vectorcall = NULL; - } - else { - op->vectorcall = _PyCFunction_Vectorcall; - } + op->vectorcall = vectorcall; _PyObject_GC_TRACK(op); return (PyObject *)op; } @@ -333,3 +364,121 @@ _PyCFunction_DebugMallocStats(FILE *out) "free PyCFunctionObject", numfree, sizeof(PyCFunctionObject)); } + + +/* Vectorcall functions for each of the PyCFunction calling conventions, + * except for METH_VARARGS (possibly combined with METH_KEYWORDS) which + * doesn't use vectorcall. + * + * First, common helpers + */ +static const char * +get_name(PyObject *func) +{ + assert(PyCFunction_Check(func)); + PyMethodDef *method = ((PyCFunctionObject *)func)->m_ml; + return method->ml_name; +} + +typedef void (*funcptr)(void); + +static inline int +cfunction_check_kwargs(PyObject *func, PyObject *kwnames) +{ + assert(!PyErr_Occurred()); + assert(PyCFunction_Check(func)); + if (kwnames && PyTuple_GET_SIZE(kwnames)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", get_name(func)); + return -1; + } + return 0; +} + +static inline funcptr +cfunction_enter_call(PyObject *func) +{ + if (Py_EnterRecursiveCall(" while calling a Python object")) { + return NULL; + } + return (funcptr)PyCFunction_GET_FUNCTION(func); +} + +/* Now the actual vectorcall functions */ +static PyObject * +cfunction_vectorcall_FASTCALL( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + if (cfunction_check_kwargs(func, kwnames)) { + return NULL; + } + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + _PyCFunctionFast meth = (_PyCFunctionFast) + cfunction_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +cfunction_vectorcall_FASTCALL_KEYWORDS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords) + cfunction_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +cfunction_vectorcall_NOARGS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + if (cfunction_check_kwargs(func, kwnames)) { + return NULL; + } + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (nargs != 0) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%zd given)", get_name(func), nargs); + return NULL; + } + PyCFunction meth = (PyCFunction)cfunction_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(PyCFunction_GET_SELF(func), NULL); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +cfunction_vectorcall_O( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + if (cfunction_check_kwargs(func, kwnames)) { + return NULL; + } + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (nargs != 1) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%zd given)", + get_name(func), nargs); + return NULL; + } + PyCFunction meth = (PyCFunction)cfunction_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(PyCFunction_GET_SELF(func), args[0]); + Py_LeaveRecursiveCall(); + return result; +} diff --git a/Objects/object.c b/Objects/object.c index 585a9748c84671..566593a9c67cc3 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -25,13 +25,14 @@ _Py_IDENTIFIER(__isabstractmethod__); int _PyObject_CheckConsistency(PyObject *op, int check_content) { - _PyObject_ASSERT(op, op != NULL); - _PyObject_ASSERT(op, !_PyObject_IsFreed(op)); - _PyObject_ASSERT(op, Py_REFCNT(op) >= 1); +#define CHECK(expr) \ + do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0) - PyTypeObject *type = op->ob_type; - _PyObject_ASSERT(op, type != NULL); - _PyType_CheckConsistency(type); + CHECK(!_PyObject_IsFreed(op)); + CHECK(Py_REFCNT(op) >= 1); + + CHECK(op->ob_type != NULL); + _PyType_CheckConsistency(op->ob_type); if (PyUnicode_Check(op)) { _PyUnicode_CheckConsistency(op, check_content); @@ -40,6 +41,8 @@ _PyObject_CheckConsistency(PyObject *op, int check_content) _PyDict_CheckConsistency(op, check_content); } return 1; + +#undef CHECK } @@ -463,41 +466,41 @@ _PyObject_IsFreed(PyObject *op) void _PyObject_Dump(PyObject* op) { - if (op == NULL) { - fprintf(stderr, "\n"); - fflush(stderr); - return; - } - if (_PyObject_IsFreed(op)) { /* It seems like the object memory has been freed: don't access it to prevent a segmentation fault. */ - fprintf(stderr, "\n"); + fprintf(stderr, "\n", op); + fflush(stderr); return; } - PyGILState_STATE gil; - PyObject *error_type, *error_value, *error_traceback; + /* 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)op->ob_refcnt); + fflush(stderr); - fprintf(stderr, "object : "); + PyTypeObject *type = Py_TYPE(op); + fprintf(stderr, "object type : %p\n", type); + fprintf(stderr, "object type name: %s\n", + type==NULL ? "NULL" : type->tp_name); + + /* the most dangerous part */ + fprintf(stderr, "object repr : "); fflush(stderr); - gil = PyGILState_Ensure(); + PyGILState_STATE gil = PyGILState_Ensure(); + PyObject *error_type, *error_value, *error_traceback; PyErr_Fetch(&error_type, &error_value, &error_traceback); + (void)PyObject_Print(op, stderr, 0); fflush(stderr); - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_Restore(error_type, error_value, error_traceback); PyGILState_Release(gil); - /* XXX(twouters) cast refcount to long until %zd is - universally available */ - fprintf(stderr, "\n" - "type : %s\n" - "refcount: %ld\n" - "address : %p\n", - Py_TYPE(op)==NULL ? "NULL" : Py_TYPE(op)->tp_name, - (long)op->ob_refcnt, - (void *)op); + + fprintf(stderr, "\n"); fflush(stderr); } @@ -2148,6 +2151,7 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, fprintf(stderr, "%s: ", function); } fflush(stderr); + if (expr) { fprintf(stderr, "Assertion \"%s\" failed", expr); } @@ -2155,25 +2159,18 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, fprintf(stderr, "Assertion failed"); } fflush(stderr); + if (msg) { fprintf(stderr, ": %s", msg); } fprintf(stderr, "\n"); fflush(stderr); - if (obj == NULL) { - fprintf(stderr, "\n"); - } - else if (_PyObject_IsFreed(obj)) { + if (_PyObject_IsFreed(obj)) { /* It seems like the object memory has been freed: don't access it to prevent a segmentation fault. */ - fprintf(stderr, "\n"); - } - else if (Py_TYPE(obj) == NULL) { - fprintf(stderr, "\n"); - } - else if (_PyObject_IsFreed((PyObject *)Py_TYPE(obj))) { - fprintf(stderr, "\n", (void *)Py_TYPE(obj)); + fprintf(stderr, "\n", obj); + fflush(stderr); } else { /* Display the traceback where the object has been allocated. @@ -2192,8 +2189,10 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, /* This might succeed or fail, but we're about to abort, so at least try to provide any extra info we can: */ _PyObject_Dump(obj); + + fprintf(stderr, "\n"); + fflush(stderr); } - fflush(stderr); Py_FatalError("_PyObject_AssertFailed"); } diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index fc7bef6199466d..bd6480a625e8a8 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -45,9 +45,9 @@ static void _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain); # define _Py_NO_ADDRESS_SAFETY_ANALYSIS \ __attribute__((no_address_safety_analysis)) # endif - // TSAN is supported since GCC 4.8, but __SANITIZE_THREAD__ macro + // TSAN is supported since GCC 5.1, but __SANITIZE_THREAD__ macro // is provided only since GCC 7. -# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +# if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) # define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) # endif #endif @@ -1415,13 +1415,13 @@ address_in_range(void *p, poolp pool) block allocations typically result in a couple of instructions). Unless the optimizer reorders everything, being too smart... - Return 1 if pymalloc allocated memory and wrote the pointer into *ptr_p. + Return a pointer to newly allocated memory if pymalloc allocated memory. - Return 0 if pymalloc failed to allocate the memory block: on bigger + Return NULL if pymalloc failed to allocate the memory block: on bigger requests, on error in the code below (as a last chance to serve the request) or when the max memory limit has been reached. */ -static int -pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) +static void* +pymalloc_alloc(void *ctx, size_t nbytes) { block *bp; poolp pool; @@ -1433,15 +1433,15 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) running_on_valgrind = RUNNING_ON_VALGRIND; } if (UNLIKELY(running_on_valgrind)) { - return 0; + return NULL; } #endif if (nbytes == 0) { - return 0; + return NULL; } if (nbytes > SMALL_REQUEST_THRESHOLD) { - return 0; + return NULL; } /* @@ -1609,19 +1609,18 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) success: assert(bp != NULL); - *ptr_p = (void *)bp; - return 1; + return (void *)bp; failed: - return 0; + return NULL; } static void * _PyObject_Malloc(void *ctx, size_t nbytes) { - void* ptr; - if (pymalloc_alloc(ctx, &ptr, nbytes)) { + void* ptr = pymalloc_alloc(ctx, nbytes); + if (ptr != NULL) { _Py_AllocatedBlocks++; return ptr; } @@ -1637,12 +1636,11 @@ _PyObject_Malloc(void *ctx, size_t nbytes) static void * _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize) { - void* ptr; - assert(elsize == 0 || nelem <= (size_t)PY_SSIZE_T_MAX / elsize); size_t nbytes = nelem * elsize; - if (pymalloc_alloc(ctx, &ptr, nbytes)) { + void *ptr = pymalloc_alloc(ctx, nbytes); + if (ptr != NULL) { memset(ptr, 0, nbytes); _Py_AllocatedBlocks++; return ptr; @@ -1743,8 +1741,8 @@ pymalloc_free(void *ctx, void *p) * are no arenas in usable_arenas with that value. */ struct arena_object* lastnf = nfp2lasta[nf]; - assert((nf == 0 && lastnf == NULL) || - (nf > 0 && + assert((nf == 0 && lastnf == NULL) || + (nf > 0 && lastnf != NULL && lastnf->nfreepools == nf && (lastnf->nextarena == NULL || @@ -2008,20 +2006,6 @@ _Py_GetAllocatedBlocks(void) * it wraps a real allocator, adding extra debugging info to the memory blocks. */ -/* Special bytes broadcast into debug memory blocks at appropriate times. - * Strings of these are unlikely to be valid addresses, floats, ints or - * 7-bit ASCII. If modified, _PyMem_IsPtrFreed() should be updated as well. - * - * Byte patterns 0xCB, 0xBB and 0xFB have been replaced with 0xCD, 0xDD and - * 0xFD to use the same values than Windows CRT debug malloc() and free(). - */ -#undef CLEANBYTE -#undef DEADBYTE -#undef FORBIDDENBYTE -#define CLEANBYTE 0xCD /* clean (newly allocated) memory */ -#define DEADBYTE 0xDD /* dead (newly freed) memory */ -#define FORBIDDENBYTE 0xFD /* untouchable bytes at each end of a block */ - /* Uncomment this define to add the "serialno" field */ /* #define PYMEM_DEBUG_SERIALNO */ @@ -2083,14 +2067,14 @@ p[0: S] p[S] API ID. See PEP 445. This is a character, but seems undocumented. p[S+1: 2*S] - Copies of FORBIDDENBYTE. Used to catch under- writes and reads. + Copies of PYMEM_FORBIDDENBYTE. Used to catch under- writes and reads. p[2*S: 2*S+n] - The requested memory, filled with copies of CLEANBYTE. + The requested memory, filled with copies of PYMEM_CLEANBYTE. Used to catch reference to uninitialized memory. &p[2*S] is returned. Note that this is 8-byte aligned if pymalloc handled the request itself. p[2*S+n: 2*S+n+S] - Copies of FORBIDDENBYTE. Used to catch over- writes and reads. + Copies of PYMEM_FORBIDDENBYTE. Used to catch over- writes and reads. p[2*S+n+S: 2*S+n+2*S] A serial number, incremented by 1 on each call to _PyMem_DebugMalloc and _PyMem_DebugRealloc. @@ -2147,15 +2131,15 @@ _PyMem_DebugRawAlloc(int use_calloc, void *ctx, size_t nbytes) /* at p, write size (SST bytes), id (1 byte), pad (SST-1 bytes) */ write_size_t(p, nbytes); p[SST] = (uint8_t)api->api_id; - memset(p + SST + 1, FORBIDDENBYTE, SST-1); + memset(p + SST + 1, PYMEM_FORBIDDENBYTE, SST-1); if (nbytes > 0 && !use_calloc) { - memset(data, CLEANBYTE, nbytes); + memset(data, PYMEM_CLEANBYTE, nbytes); } /* at tail, write pad (SST bytes) and serialno (SST bytes) */ tail = data + nbytes; - memset(tail, FORBIDDENBYTE, SST); + memset(tail, PYMEM_FORBIDDENBYTE, SST); #ifdef PYMEM_DEBUG_SERIALNO write_size_t(tail + SST, serialno); #endif @@ -2181,7 +2165,7 @@ _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize) /* The debug free first checks the 2*SST bytes on each end for sanity (in particular, that the FORBIDDENBYTEs with the api ID are still intact). - Then fills the original bytes with DEADBYTE. + Then fills the original bytes with PYMEM_DEADBYTE. Then calls the underlying free. */ static void @@ -2199,7 +2183,7 @@ _PyMem_DebugRawFree(void *ctx, void *p) _PyMem_DebugCheckAddress(api->api_id, p); nbytes = read_size_t(q); nbytes += PYMEM_DEBUG_EXTRA_BYTES; - memset(q, DEADBYTE, nbytes); + memset(q, PYMEM_DEADBYTE, nbytes); api->alloc.free(api->alloc.ctx, q); } @@ -2241,14 +2225,14 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes) */ if (original_nbytes <= sizeof(save)) { memcpy(save, data, original_nbytes); - memset(data - 2 * SST, DEADBYTE, + memset(data - 2 * SST, PYMEM_DEADBYTE, original_nbytes + PYMEM_DEBUG_EXTRA_BYTES); } else { memcpy(save, data, ERASED_SIZE); - memset(head, DEADBYTE, ERASED_SIZE + 2 * SST); + memset(head, PYMEM_DEADBYTE, ERASED_SIZE + 2 * SST); memcpy(&save[ERASED_SIZE], tail - ERASED_SIZE, ERASED_SIZE); - memset(tail - ERASED_SIZE, DEADBYTE, + memset(tail - ERASED_SIZE, PYMEM_DEADBYTE, ERASED_SIZE + PYMEM_DEBUG_EXTRA_BYTES - 2 * SST); } @@ -2270,10 +2254,10 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes) write_size_t(head, nbytes); head[SST] = (uint8_t)api->api_id; - memset(head + SST + 1, FORBIDDENBYTE, SST-1); + memset(head + SST + 1, PYMEM_FORBIDDENBYTE, SST-1); tail = data + nbytes; - memset(tail, FORBIDDENBYTE, SST); + memset(tail, PYMEM_FORBIDDENBYTE, SST); #ifdef PYMEM_DEBUG_SERIALNO write_size_t(tail + SST, block_serialno); #endif @@ -2297,7 +2281,8 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes) if (nbytes > original_nbytes) { /* growing: mark new extra memory clean */ - memset(data + original_nbytes, CLEANBYTE, nbytes - original_nbytes); + memset(data + original_nbytes, PYMEM_CLEANBYTE, + nbytes - original_nbytes); } return data; @@ -2376,7 +2361,7 @@ _PyMem_DebugCheckAddress(char api, const void *p) * the tail could lead to a segfault then. */ for (i = SST-1; i >= 1; --i) { - if (*(q-i) != FORBIDDENBYTE) { + if (*(q-i) != PYMEM_FORBIDDENBYTE) { msg = "bad leading pad byte"; goto error; } @@ -2385,7 +2370,7 @@ _PyMem_DebugCheckAddress(char api, const void *p) nbytes = read_size_t(q - 2*SST); tail = q + nbytes; for (i = 0; i < SST; ++i) { - if (tail[i] != FORBIDDENBYTE) { + if (tail[i] != PYMEM_FORBIDDENBYTE) { msg = "bad trailing pad byte"; goto error; } @@ -2425,7 +2410,7 @@ _PyObject_DebugDumpAddress(const void *p) fprintf(stderr, " The %d pad bytes at p-%d are ", SST-1, SST-1); ok = 1; for (i = 1; i <= SST-1; ++i) { - if (*(q-i) != FORBIDDENBYTE) { + if (*(q-i) != PYMEM_FORBIDDENBYTE) { ok = 0; break; } @@ -2434,11 +2419,11 @@ _PyObject_DebugDumpAddress(const void *p) fputs("FORBIDDENBYTE, as expected.\n", stderr); else { fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n", - FORBIDDENBYTE); + PYMEM_FORBIDDENBYTE); for (i = SST-1; i >= 1; --i) { const uint8_t byte = *(q-i); fprintf(stderr, " at p-%d: 0x%02x", i, byte); - if (byte != FORBIDDENBYTE) + if (byte != PYMEM_FORBIDDENBYTE) fputs(" *** OUCH", stderr); fputc('\n', stderr); } @@ -2453,7 +2438,7 @@ _PyObject_DebugDumpAddress(const void *p) fprintf(stderr, " The %d pad bytes at tail=%p are ", SST, (void *)tail); ok = 1; for (i = 0; i < SST; ++i) { - if (tail[i] != FORBIDDENBYTE) { + if (tail[i] != PYMEM_FORBIDDENBYTE) { ok = 0; break; } @@ -2462,12 +2447,12 @@ _PyObject_DebugDumpAddress(const void *p) fputs("FORBIDDENBYTE, as expected.\n", stderr); else { fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n", - FORBIDDENBYTE); + PYMEM_FORBIDDENBYTE); for (i = 0; i < SST; ++i) { const uint8_t byte = tail[i]; fprintf(stderr, " at tail+%d: 0x%02x", i, byte); - if (byte != FORBIDDENBYTE) + if (byte != PYMEM_FORBIDDENBYTE) fputs(" *** OUCH", stderr); fputc('\n', stderr); } diff --git a/Objects/setobject.c b/Objects/setobject.c index bd031600c1be66..f8ae0c05e273cb 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1456,10 +1456,6 @@ PyDoc_STRVAR(isdisjoint_doc, static int set_difference_update_internal(PySetObject *so, PyObject *other) { - if (PySet_GET_SIZE(so) == 0) { - return 0; - } - if ((PyObject *)so == other) return set_clear_internal(so); @@ -1534,10 +1530,6 @@ set_difference(PySetObject *so, PyObject *other) Py_ssize_t pos = 0, other_size; int rv; - if (PySet_GET_SIZE(so) == 0) { - return set_copy(so, NULL); - } - if (PyAnySet_Check(other)) { other_size = PySet_GET_SIZE(other); } @@ -1962,9 +1954,10 @@ set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored)) args = PyTuple_Pack(1, keys); if (args == NULL) goto done; - dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__); + if (_PyObject_LookupAttrId((PyObject *)so, &PyId___dict__, &dict) < 0) { + goto done; + } if (dict == NULL) { - PyErr_Clear(); dict = Py_None; Py_INCREF(dict); } diff --git a/Objects/stringlib/clinic/transmogrify.h.h b/Objects/stringlib/clinic/transmogrify.h.h index 0c53a75b1bf834..8a3a060f12bc9e 100644 --- a/Objects/stringlib/clinic/transmogrify.h.h +++ b/Objects/stringlib/clinic/transmogrify.h.h @@ -100,7 +100,7 @@ stringlib_ljust(PyObject *self, PyObject *const *args, Py_ssize_t nargs) fillchar = PyByteArray_AS_STRING(args[1])[0]; } else { - _PyArg_BadArgument("ljust", 2, "a byte string of length 1", args[1]); + _PyArg_BadArgument("ljust", "argument 2", "a byte string of length 1", args[1]); goto exit; } skip_optional: @@ -161,7 +161,7 @@ stringlib_rjust(PyObject *self, PyObject *const *args, Py_ssize_t nargs) fillchar = PyByteArray_AS_STRING(args[1])[0]; } else { - _PyArg_BadArgument("rjust", 2, "a byte string of length 1", args[1]); + _PyArg_BadArgument("rjust", "argument 2", "a byte string of length 1", args[1]); goto exit; } skip_optional: @@ -222,7 +222,7 @@ stringlib_center(PyObject *self, PyObject *const *args, Py_ssize_t nargs) fillchar = PyByteArray_AS_STRING(args[1])[0]; } else { - _PyArg_BadArgument("center", 2, "a byte string of length 1", args[1]); + _PyArg_BadArgument("center", "argument 2", "a byte string of length 1", args[1]); goto exit; } skip_optional: @@ -274,4 +274,4 @@ stringlib_zfill(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=96cbb19b238d0e84 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=15be047aef999b4e input=a9049054013a1b77]*/ diff --git a/Objects/stringlib/codecs.h b/Objects/stringlib/codecs.h index 8645bc26cff8ca..d6f2b98f2b30a3 100644 --- a/Objects/stringlib/codecs.h +++ b/Objects/stringlib/codecs.h @@ -207,7 +207,7 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, goto InvalidContinuation1; } else if (ch == 0xF4 && ch2 >= 0x90) { /* invalid sequence - \xF4\x90\x80\80- -- 110000- overflow */ + \xF4\x90\x80\x80- -- 110000- overflow */ goto InvalidContinuation1; } if (!IS_CONTINUATION_BYTE(ch3)) { @@ -573,10 +573,10 @@ STRINGLIB(utf16_decode)(const unsigned char **inptr, const unsigned char *e, } /* UTF-16 code pair: */ - if (q >= e) - goto UnexpectedEnd; if (!Py_UNICODE_IS_HIGH_SURROGATE(ch)) goto IllegalEncoding; + if (q >= e) + goto UnexpectedEnd; ch2 = (q[ihi] << 8) | q[ilo]; q += 2; if (!Py_UNICODE_IS_LOW_SURROGATE(ch2)) diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h index 46fcf356d0d0f5..56a4467d353813 100644 --- a/Objects/stringlib/fastsearch.h +++ b/Objects/stringlib/fastsearch.h @@ -52,7 +52,7 @@ STRINGLIB(find_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) return (p - s); return -1; #else - /* use memchr if we can choose a needle without two many likely + /* use memchr if we can choose a needle without too many likely false positives */ const STRINGLIB_CHAR *s1, *e1; unsigned char needle = ch & 0xff; @@ -111,7 +111,7 @@ STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) return (p - s); return -1; #else - /* use memrchr if we can choose a needle without two many likely + /* use memrchr if we can choose a needle without too many likely false positives */ const STRINGLIB_CHAR *s1; Py_ssize_t n1; diff --git a/Objects/structseq.c b/Objects/structseq.c index 2c25e1646a2a67..c158afccb97fdd 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -1,5 +1,11 @@ -/* Implementation helper: a struct that looks like a tuple. See timemodule - and posixmodule for example uses. */ +/* Implementation helper: a struct that looks like a tuple. + See timemodule and posixmodule for example uses. + + The structseq helper is considered an internal CPython implementation + detail. Docs for modules using structseqs should call them + "named tuples" (be sure to include a space between the two + words and add a link back to the term in Docs/glossary.rst). +*/ #include "Python.h" #include "pycore_tupleobject.h" @@ -101,12 +107,12 @@ class structseq "PyStructSequence *" "NULL" @classmethod structseq.__new__ as structseq_new sequence as arg: object - dict: object = NULL + dict: object(c_default="NULL") = {} [clinic start generated code]*/ static PyObject * structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) -/*[clinic end generated code: output=baa082e788b171da input=9b44810243907377]*/ +/*[clinic end generated code: output=baa082e788b171da input=90532511101aa3fb]*/ { PyObject *ob; PyStructSequence *res = NULL; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 006df8d1f090d5..5df121775af00d 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -117,7 +117,7 @@ find_signature(const char *name, const char *doc) #define SIGNATURE_END_MARKER ")\n--\n\n" #define SIGNATURE_END_MARKER_LENGTH 6 /* - * skips past the end of the docstring's instrospection signature. + * skips past the end of the docstring's introspection signature. * (assumes doc starts with a valid signature prefix.) */ static const char * @@ -137,22 +137,24 @@ skip_signature(const char *doc) int _PyType_CheckConsistency(PyTypeObject *type) { -#define ASSERT(expr) _PyObject_ASSERT((PyObject *)type, (expr)) +#define CHECK(expr) \ + do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG((PyObject *)type, Py_STRINGIFY(expr)); } } while (0) + + CHECK(!_PyObject_IsFreed((PyObject *)type)); if (!(type->tp_flags & Py_TPFLAGS_READY)) { - /* don't check types before PyType_Ready() */ + /* don't check static types before PyType_Ready() */ return 1; } - ASSERT(!_PyObject_IsFreed((PyObject *)type)); - ASSERT(Py_REFCNT(type) >= 1); - ASSERT(PyType_Check(type)); + CHECK(Py_REFCNT(type) >= 1); + CHECK(PyType_Check(type)); - ASSERT(!(type->tp_flags & Py_TPFLAGS_READYING)); - ASSERT(type->tp_dict != NULL); + CHECK(!(type->tp_flags & Py_TPFLAGS_READYING)); + CHECK(type->tp_dict != NULL); return 1; -#undef ASSERT +#undef CHECK } static const char * @@ -1157,11 +1159,9 @@ subtype_dealloc(PyObject *self) /* Test whether the type has GC exactly once */ if (!PyType_IS_GC(type)) { - /* It's really rare to find a dynamic type that doesn't have - GC; it can only happen when deriving from 'object' and not - adding any slots or instance variables. This allows - certain simplifications: there's no need to call - clear_slots(), or DECREF the dict, or clear weakrefs. */ + /* A non GC dynamic type allows certain simplifications: + there's no need to call clear_slots(), or DECREF the dict, + or clear weakrefs. */ /* Maybe call finalizer; exit early if resurrected */ if (type->tp_finalize) { @@ -1177,7 +1177,6 @@ subtype_dealloc(PyObject *self) /* Find the nearest base with a different tp_dealloc */ base = type; while ((basedealloc = base->tp_dealloc) == subtype_dealloc) { - assert(Py_SIZE(base) == 0); base = base->tp_base; assert(base); } @@ -1189,8 +1188,10 @@ subtype_dealloc(PyObject *self) assert(basedealloc); basedealloc(self); - /* Can't reference self beyond this point */ - Py_DECREF(type); + /* Only decref if the base type is not already a heap allocated type. + Otherwise, basedealloc should have decref'd it already */ + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE && !(base->tp_flags & Py_TPFLAGS_HEAPTYPE)) + Py_DECREF(type); /* Done */ return; @@ -1289,8 +1290,9 @@ subtype_dealloc(PyObject *self) /* Can't reference self beyond this point. It's possible tp_del switched our type from a HEAPTYPE to a non-HEAPTYPE, so be careful about - reference counting. */ - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) + reference counting. Only decref if the base type is not already a heap + allocated type. Otherwise, basedealloc should have decref'd it already */ + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE && !(base->tp_flags & Py_TPFLAGS_HEAPTYPE)) Py_DECREF(type); endlabel: @@ -1412,7 +1414,7 @@ lookup_maybe_method(PyObject *self, _Py_Identifier *attrid, int *unbound) return NULL; } - if (PyFunction_Check(res)) { + if (PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)) { /* Avoid temporary PyMethodObject */ *unbound = 1; Py_INCREF(res); @@ -1547,17 +1549,10 @@ tail_contains(PyObject *tuple, int whence, PyObject *o) static PyObject * class_name(PyObject *cls) { - PyObject *name = _PyObject_GetAttrId(cls, &PyId___name__); - if (name == NULL) { - PyErr_Clear(); + PyObject *name; + if (_PyObject_LookupAttrId(cls, &PyId___name__, &name) == 0) { name = PyObject_Repr(cls); } - if (name == NULL) - return NULL; - if (!PyUnicode_Check(name)) { - Py_DECREF(name); - return NULL; - } return name; } @@ -1575,13 +1570,15 @@ check_duplicates(PyObject *tuple) if (PyTuple_GET_ITEM(tuple, j) == o) { o = class_name(o); if (o != NULL) { - PyErr_Format(PyExc_TypeError, - "duplicate base class %U", - o); + if (PyUnicode_Check(o)) { + PyErr_Format(PyExc_TypeError, + "duplicate base class %U", o); + } + else { + PyErr_SetString(PyExc_TypeError, + "duplicate base class"); + } Py_DECREF(o); - } else { - PyErr_SetString(PyExc_TypeError, - "duplicate base class"); } return -1; } @@ -1625,13 +1622,20 @@ consistent method resolution\norder (MRO) for bases"); i = 0; while (PyDict_Next(set, &i, &k, &v) && (size_t)off < sizeof(buf)) { PyObject *name = class_name(k); - const char *name_str; + const char *name_str = NULL; if (name != NULL) { - name_str = PyUnicode_AsUTF8(name); - if (name_str == NULL) + if (PyUnicode_Check(name)) { + name_str = PyUnicode_AsUTF8(name); + } + else { name_str = "?"; - } else - name_str = "?"; + } + } + if (name_str == NULL) { + Py_XDECREF(name); + Py_DECREF(set); + return; + } off += PyOS_snprintf(buf + off, sizeof(buf) - off, " %s", name_str); Py_XDECREF(name); if (--n && (size_t)(off+1) < sizeof(buf)) { @@ -3418,10 +3422,10 @@ merge_class_dict(PyObject *dict, PyObject *aclass) assert(aclass); /* Merge in the type's dict (if any). */ - classdict = _PyObject_GetAttrId(aclass, &PyId___dict__); - if (classdict == NULL) - PyErr_Clear(); - else { + if (_PyObject_LookupAttrId(aclass, &PyId___dict__, &classdict) < 0) { + return -1; + } + if (classdict != NULL) { int status = PyDict_Update(dict, classdict); Py_DECREF(classdict); if (status < 0) @@ -3429,15 +3433,17 @@ merge_class_dict(PyObject *dict, PyObject *aclass) } /* Recursively merge in the base types' (if any) dicts. */ - bases = _PyObject_GetAttrId(aclass, &PyId___bases__); - if (bases == NULL) - PyErr_Clear(); - else { + if (_PyObject_LookupAttrId(aclass, &PyId___bases__, &bases) < 0) { + return -1; + } + if (bases != NULL) { /* We have no guarantee that bases is a real tuple */ Py_ssize_t i, n; n = PySequence_Size(bases); /* This better be right */ - if (n < 0) - PyErr_Clear(); + if (n < 0) { + Py_DECREF(bases); + return -1; + } else { for (i = 0; i < n; i++) { int status; @@ -4725,9 +4731,10 @@ object___dir___impl(PyObject *self) PyObject *itsclass = NULL; /* Get __dict__ (which may or may not be a real dict...) */ - dict = _PyObject_GetAttrId(self, &PyId___dict__); + if (_PyObject_LookupAttrId(self, &PyId___dict__, &dict) < 0) { + return NULL; + } if (dict == NULL) { - PyErr_Clear(); dict = PyDict_New(); } else if (!PyDict_Check(dict)) { @@ -4745,12 +4752,12 @@ object___dir___impl(PyObject *self) goto error; /* Merge in attrs reachable from its class. */ - itsclass = _PyObject_GetAttrId(self, &PyId___class__); - if (itsclass == NULL) - /* XXX(tomer): Perhaps fall back to obj->ob_type if no - __class__ exists? */ - PyErr_Clear(); - else if (merge_class_dict(dict, itsclass) != 0) + if (_PyObject_LookupAttrId(self, &PyId___class__, &itsclass) < 0) { + goto error; + } + /* XXX(tomer): Perhaps fall back to obj->ob_type if no + __class__ exists? */ + if (itsclass != NULL && merge_class_dict(dict, itsclass) < 0) goto error; result = PyDict_Keys(dict); @@ -5148,15 +5155,15 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) COPYSLOT(tp_repr); /* tp_hash see tp_richcompare */ { - /* Inherit tp_vectorcall_offset only if tp_call is not overridden */ - if (!type->tp_call) { - COPYSLOT(tp_vectorcall_offset); - } - /* Inherit_Py_TPFLAGS_HAVE_VECTORCALL for non-heap types + /* Always inherit tp_vectorcall_offset to support PyVectorcall_Call(). + * If _Py_TPFLAGS_HAVE_VECTORCALL is not inherited, then vectorcall + * won't be used automatically. */ + COPYSLOT(tp_vectorcall_offset); + + /* Inherit _Py_TPFLAGS_HAVE_VECTORCALL for non-heap types * if tp_call is not overridden */ if (!type->tp_call && (base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) && - !(type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) && !(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL; @@ -6105,16 +6112,19 @@ method_is_overloaded(PyObject *left, PyObject *right, struct _Py_Identifier *nam PyObject *a, *b; int ok; - b = _PyObject_GetAttrId((PyObject *)(Py_TYPE(right)), name); + if (_PyObject_LookupAttrId((PyObject *)(Py_TYPE(right)), name, &b) < 0) { + return -1; + } if (b == NULL) { - PyErr_Clear(); /* If right doesn't have it, it's not overloaded */ return 0; } - a = _PyObject_GetAttrId((PyObject *)(Py_TYPE(left)), name); + if (_PyObject_LookupAttrId((PyObject *)(Py_TYPE(left)), name, &a) < 0) { + Py_DECREF(b); + return -1; + } if (a == NULL) { - PyErr_Clear(); Py_DECREF(b); /* If right has it but left doesn't, it's overloaded */ return 1; @@ -6123,11 +6133,6 @@ method_is_overloaded(PyObject *left, PyObject *right, struct _Py_Identifier *nam ok = PyObject_RichCompareBool(a, b, Py_NE); Py_DECREF(a); Py_DECREF(b); - if (ok < 0) { - PyErr_Clear(); - return 0; - } - return ok; } @@ -6145,15 +6150,19 @@ FUNCNAME(PyObject *self, PyObject *other) \ if (Py_TYPE(self)->tp_as_number != NULL && \ Py_TYPE(self)->tp_as_number->SLOTNAME == TESTFUNC) { \ PyObject *r; \ - if (do_other && \ - PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self)) && \ - method_is_overloaded(self, other, &rop_id)) { \ - stack[0] = self; \ - r = call_maybe(other, &rop_id, stack, 1); \ - if (r != Py_NotImplemented) \ - return r; \ - Py_DECREF(r); \ - do_other = 0; \ + if (do_other && PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) { \ + int ok = method_is_overloaded(self, other, &rop_id); \ + if (ok < 0) { \ + return NULL; \ + } \ + if (ok) { \ + stack[0] = self; \ + r = call_maybe(other, &rop_id, stack, 1); \ + if (r != Py_NotImplemented) \ + return r; \ + Py_DECREF(r); \ + do_other = 0; \ + } \ } \ stack[0] = other; \ r = call_maybe(self, &op_id, stack, 1); \ @@ -7236,14 +7245,21 @@ update_one_slot(PyTypeObject *type, slotdef *p) if (tptr == NULL || tptr == ptr) generic = p->function; d = (PyWrapperDescrObject *)descr; - if (d->d_base->wrapper == p->wrapper && + if ((specific == NULL || specific == d->d_wrapped) && + d->d_base->wrapper == p->wrapper && PyType_IsSubtype(type, PyDescr_TYPE(d))) { - if (specific == NULL || - specific == d->d_wrapped) - specific = d->d_wrapped; - else - use_generic = 1; + specific = d->d_wrapped; + } + else { + /* We cannot use the specific slot function because either + - it is not unique: there are multiple methods for this + slot and they conflict + - the signature is wrong (as checked by the ->wrapper + comparison above) + - it's wrapping the wrong class + */ + use_generic = 1; } } else if (Py_TYPE(descr) == &PyCFunction_Type && @@ -7739,7 +7755,9 @@ supercheck(PyTypeObject *type, PyObject *obj) /* Try the slow way */ PyObject *class_attr; - class_attr = _PyObject_GetAttrId(obj, &PyId___class__); + if (_PyObject_LookupAttrId(obj, &PyId___class__, &class_attr) < 0) { + return NULL; + } if (class_attr != NULL && PyType_Check(class_attr) && (PyTypeObject *)class_attr != Py_TYPE(obj)) @@ -7749,11 +7767,7 @@ supercheck(PyTypeObject *type, PyObject *obj) if (ok) return (PyTypeObject *)class_attr; } - - if (class_attr == NULL) - PyErr_Clear(); - else - Py_DECREF(class_attr); + Py_XDECREF(class_attr); } PyErr_SetString(PyExc_TypeError, diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 6ec4127ff385b3..0556eff8d07132 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -442,17 +442,21 @@ PyUnicode_GetMax(void) int _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; - _PyObject_ASSERT(op, PyUnicode_Check(op)); + assert(op != NULL); + CHECK(PyUnicode_Check(op)); ascii = (PyASCIIObject *)op; kind = ascii->state.kind; if (ascii->state.ascii == 1 && ascii->state.compact == 1) { - _PyObject_ASSERT(op, kind == PyUnicode_1BYTE_KIND); - _PyObject_ASSERT(op, ascii->state.ready == 1); + CHECK(kind == PyUnicode_1BYTE_KIND); + CHECK(ascii->state.ready == 1); } else { PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op; @@ -460,41 +464,41 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) if (ascii->state.compact == 1) { data = compact + 1; - _PyObject_ASSERT(op, kind == PyUnicode_1BYTE_KIND + CHECK(kind == PyUnicode_1BYTE_KIND || kind == PyUnicode_2BYTE_KIND || kind == PyUnicode_4BYTE_KIND); - _PyObject_ASSERT(op, ascii->state.ascii == 0); - _PyObject_ASSERT(op, ascii->state.ready == 1); - _PyObject_ASSERT(op, compact->utf8 != data); + CHECK(ascii->state.ascii == 0); + CHECK(ascii->state.ready == 1); + CHECK(compact->utf8 != data); } else { PyUnicodeObject *unicode = (PyUnicodeObject *)op; data = unicode->data.any; if (kind == PyUnicode_WCHAR_KIND) { - _PyObject_ASSERT(op, ascii->length == 0); - _PyObject_ASSERT(op, ascii->hash == -1); - _PyObject_ASSERT(op, ascii->state.compact == 0); - _PyObject_ASSERT(op, ascii->state.ascii == 0); - _PyObject_ASSERT(op, ascii->state.ready == 0); - _PyObject_ASSERT(op, ascii->state.interned == SSTATE_NOT_INTERNED); - _PyObject_ASSERT(op, ascii->wstr != NULL); - _PyObject_ASSERT(op, data == NULL); - _PyObject_ASSERT(op, compact->utf8 == NULL); + 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); } else { - _PyObject_ASSERT(op, kind == PyUnicode_1BYTE_KIND + CHECK(kind == PyUnicode_1BYTE_KIND || kind == PyUnicode_2BYTE_KIND || kind == PyUnicode_4BYTE_KIND); - _PyObject_ASSERT(op, ascii->state.compact == 0); - _PyObject_ASSERT(op, ascii->state.ready == 1); - _PyObject_ASSERT(op, data != NULL); + CHECK(ascii->state.compact == 0); + CHECK(ascii->state.ready == 1); + CHECK(data != NULL); if (ascii->state.ascii) { - _PyObject_ASSERT(op, compact->utf8 == data); - _PyObject_ASSERT(op, compact->utf8_length == ascii->length); + CHECK(compact->utf8 == data); + CHECK(compact->utf8_length == ascii->length); } else - _PyObject_ASSERT(op, compact->utf8 != data); + CHECK(compact->utf8 != data); } } if (kind != PyUnicode_WCHAR_KIND) { @@ -506,16 +510,16 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) #endif ) { - _PyObject_ASSERT(op, ascii->wstr == data); - _PyObject_ASSERT(op, compact->wstr_length == ascii->length); + CHECK(ascii->wstr == data); + CHECK(compact->wstr_length == ascii->length); } else - _PyObject_ASSERT(op, ascii->wstr != data); + CHECK(ascii->wstr != data); } if (compact->utf8 == NULL) - _PyObject_ASSERT(op, compact->utf8_length == 0); + CHECK(compact->utf8_length == 0); if (ascii->wstr == NULL) - _PyObject_ASSERT(op, compact->wstr_length == 0); + CHECK(compact->wstr_length == 0); } /* check that the best kind is used: O(n) operation */ @@ -534,23 +538,25 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) } if (kind == PyUnicode_1BYTE_KIND) { if (ascii->state.ascii == 0) { - _PyObject_ASSERT(op, maxchar >= 128); - _PyObject_ASSERT(op, maxchar <= 255); + CHECK(maxchar >= 128); + CHECK(maxchar <= 255); } else - _PyObject_ASSERT(op, maxchar < 128); + CHECK(maxchar < 128); } else if (kind == PyUnicode_2BYTE_KIND) { - _PyObject_ASSERT(op, maxchar >= 0x100); - _PyObject_ASSERT(op, maxchar <= 0xFFFF); + CHECK(maxchar >= 0x100); + CHECK(maxchar <= 0xFFFF); } else { - _PyObject_ASSERT(op, maxchar >= 0x10000); - _PyObject_ASSERT(op, maxchar <= MAX_UNICODE); + CHECK(maxchar >= 0x10000); + CHECK(maxchar <= MAX_UNICODE); } - _PyObject_ASSERT(op, PyUnicode_READ(kind, data, ascii->length) == 0); + CHECK(PyUnicode_READ(kind, data, ascii->length) == 0); } return 1; + +#undef CHECK } @@ -4937,11 +4943,15 @@ unicode_decode_utf8(const char *s, Py_ssize_t size, endinpos = startinpos + 1; break; case 2: - case 3: - case 4: - if (s == end || consumed) { + if (consumed && (unsigned char)s[0] == 0xED && end - s == 2 + && (unsigned char)s[1] >= 0xA0 && (unsigned char)s[1] <= 0xBF) + { + /* Truncated surrogate code in range D800-DFFF */ goto End; } + /* fall through */ + case 3: + case 4: errmsg = "invalid continuation byte"; startinpos = s - starts; endinpos = startinpos + ch - 1; @@ -7114,6 +7124,12 @@ PyUnicode_AsASCIIString(PyObject *unicode) #define NEED_RETRY #endif +/* INT_MAX is the theoretical largest chunk (or INT_MAX / 2 when + transcoding from UTF-16), but INT_MAX / 4 perfoms better in + both cases also and avoids partial characters overrunning the + length limit in MultiByteToWideChar on Windows */ +#define DECODING_CHUNK_SIZE (INT_MAX/4) + #ifndef WC_ERR_INVALID_CHARS # define WC_ERR_INVALID_CHARS 0x0080 #endif @@ -7350,8 +7366,8 @@ decode_code_page_stateful(int code_page, do { #ifdef NEED_RETRY - if (size > INT_MAX) { - chunk_size = INT_MAX; + if (size > DECODING_CHUNK_SIZE) { + chunk_size = DECODING_CHUNK_SIZE; final = 0; done = 0; } @@ -7755,10 +7771,8 @@ encode_code_page(int code_page, do { #ifdef NEED_RETRY - /* UTF-16 encoding may double the size, so use only INT_MAX/2 - chunks. */ - if (len > INT_MAX/2) { - chunk_len = INT_MAX/2; + if (len > DECODING_CHUNK_SIZE) { + chunk_len = DECODING_CHUNK_SIZE; done = 0; } else @@ -12441,7 +12455,7 @@ do_strip(PyObject *self, int striptype) static PyObject * do_argstrip(PyObject *self, int striptype, PyObject *sep) { - if (sep != NULL && sep != Py_None) { + if (sep != Py_None) { if (PyUnicode_Check(sep)) return _PyUnicode_XStrip(self, striptype, sep); else { @@ -12462,14 +12476,14 @@ str.strip as unicode_strip chars: object = None / -Return a copy of the string with leading and trailing whitespace remove. +Return a copy of the string with leading and trailing whitespace removed. If chars is given and not None, remove characters in chars instead. [clinic start generated code]*/ static PyObject * unicode_strip_impl(PyObject *self, PyObject *chars) -/*[clinic end generated code: output=ca19018454345d57 input=eefe24a1059c352b]*/ +/*[clinic end generated code: output=ca19018454345d57 input=385289c6f423b954]*/ { return do_argstrip(self, BOTHSTRIP, chars); } @@ -12478,7 +12492,7 @@ unicode_strip_impl(PyObject *self, PyObject *chars) /*[clinic input] str.lstrip as unicode_lstrip - chars: object = NULL + chars: object = None / Return a copy of the string with leading whitespace removed. @@ -12488,7 +12502,7 @@ If chars is given and not None, remove characters in chars instead. static PyObject * unicode_lstrip_impl(PyObject *self, PyObject *chars) -/*[clinic end generated code: output=3b43683251f79ca7 input=9e56f3c45f5ff4c3]*/ +/*[clinic end generated code: output=3b43683251f79ca7 input=529f9f3834448671]*/ { return do_argstrip(self, LEFTSTRIP, chars); } @@ -12497,7 +12511,7 @@ unicode_lstrip_impl(PyObject *self, PyObject *chars) /*[clinic input] str.rstrip as unicode_rstrip - chars: object = NULL + chars: object = None / Return a copy of the string with trailing whitespace removed. @@ -12507,7 +12521,7 @@ If chars is given and not None, remove characters in chars instead. static PyObject * unicode_rstrip_impl(PyObject *self, PyObject *chars) -/*[clinic end generated code: output=4a59230017cc3b7a input=ac89d0219cb411ee]*/ +/*[clinic end generated code: output=4a59230017cc3b7a input=62566c627916557f]*/ { return do_argstrip(self, RIGHTSTRIP, chars); } @@ -15713,13 +15727,13 @@ config_get_codec_name(wchar_t **config_encoding) static PyStatus -init_stdio_encoding(PyInterpreterState *interp) +init_stdio_encoding(PyThreadState *tstate) { /* Update the stdio encoding to the normalized Python codec name. */ - PyConfig *config = &interp->config; + PyConfig *config = &tstate->interp->config; if (config_get_codec_name(&config->stdio_encoding) < 0) { return _PyStatus_ERR("failed to get the Python codec name " - "of the stdio encoding"); + "of the stdio encoding"); } return _PyStatus_OK(); } @@ -15773,15 +15787,18 @@ init_fs_codec(PyInterpreterState *interp) static PyStatus -init_fs_encoding(PyInterpreterState *interp) +init_fs_encoding(PyThreadState *tstate) { + PyInterpreterState *interp = tstate->interp; + /* Update the filesystem encoding to the normalized Python codec name. For example, replace "ANSI_X3.4-1968" (locale encoding) with "ascii" (Python codec name). */ PyConfig *config = &interp->config; if (config_get_codec_name(&config->filesystem_encoding) < 0) { + _Py_DumpPathConfig(tstate); return _PyStatus_ERR("failed to get the Python codec " - "of the filesystem encoding"); + "of the filesystem encoding"); } if (init_fs_codec(interp) < 0) { @@ -15792,14 +15809,14 @@ init_fs_encoding(PyInterpreterState *interp) PyStatus -_PyUnicode_InitEncodings(PyInterpreterState *interp) +_PyUnicode_InitEncodings(PyThreadState *tstate) { - PyStatus status = init_fs_encoding(interp); + PyStatus status = init_fs_encoding(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - return init_stdio_encoding(interp); + return init_stdio_encoding(tstate); } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 8b8e71031afa6b..58fe09fa3b51b0 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -145,11 +145,14 @@ weakref_hash(PyWeakReference *self) { if (self->hash != -1) return self->hash; - if (PyWeakref_GET_OBJECT(self) == Py_None) { + PyObject* obj = PyWeakref_GET_OBJECT(self); + if (obj == Py_None) { PyErr_SetString(PyExc_TypeError, "weak object has gone away"); return -1; } - self->hash = PyObject_Hash(PyWeakref_GET_OBJECT(self)); + Py_INCREF(obj); + self->hash = PyObject_Hash(obj); + Py_DECREF(obj); return self->hash; } @@ -159,28 +162,33 @@ weakref_repr(PyWeakReference *self) { PyObject *name, *repr; _Py_IDENTIFIER(__name__); + PyObject* obj = PyWeakref_GET_OBJECT(self); - if (PyWeakref_GET_OBJECT(self) == Py_None) + if (obj == Py_None) { return PyUnicode_FromFormat("", self); + } - name = _PyObject_GetAttrId(PyWeakref_GET_OBJECT(self), &PyId___name__); + Py_INCREF(obj); + if (_PyObject_LookupAttrId(obj, &PyId___name__, &name) < 0) { + Py_DECREF(obj); + return NULL; + } if (name == NULL || !PyUnicode_Check(name)) { - if (name == NULL) - PyErr_Clear(); repr = PyUnicode_FromFormat( "", self, Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name, - PyWeakref_GET_OBJECT(self)); + obj); } else { repr = PyUnicode_FromFormat( "", self, Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name, - PyWeakref_GET_OBJECT(self), + obj, name); } + Py_DECREF(obj); Py_XDECREF(name); return repr; } @@ -207,8 +215,14 @@ weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op) else Py_RETURN_FALSE; } - return PyObject_RichCompare(PyWeakref_GET_OBJECT(self), - PyWeakref_GET_OBJECT(other), op); + PyObject* obj = PyWeakref_GET_OBJECT(self); + PyObject* other_obj = PyWeakref_GET_OBJECT(other); + Py_INCREF(obj); + Py_INCREF(other_obj); + PyObject* res = PyObject_RichCompare(obj, other_obj, op); + Py_DECREF(obj); + Py_DECREF(other_obj); + return res; } /* Given the head of an object's list of weak references, extract the @@ -415,18 +429,14 @@ proxy_checkref(PyWeakReference *proxy) o = PyWeakref_GET_OBJECT(o); \ } -#define UNWRAP_I(o) \ - if (PyWeakref_CheckProxy(o)) { \ - if (!proxy_checkref((PyWeakReference *)o)) \ - return -1; \ - o = PyWeakref_GET_OBJECT(o); \ - } - #define WRAP_UNARY(method, generic) \ static PyObject * \ method(PyObject *proxy) { \ UNWRAP(proxy); \ - return generic(proxy); \ + Py_INCREF(proxy); \ + PyObject* res = generic(proxy); \ + Py_DECREF(proxy); \ + return res; \ } #define WRAP_BINARY(method, generic) \ @@ -434,7 +444,12 @@ proxy_checkref(PyWeakReference *proxy) method(PyObject *x, PyObject *y) { \ UNWRAP(x); \ UNWRAP(y); \ - return generic(x, y); \ + Py_INCREF(x); \ + Py_INCREF(y); \ + PyObject* res = generic(x, y); \ + Py_DECREF(x); \ + Py_DECREF(y); \ + return res; \ } /* Note that the third arg needs to be checked for NULL since the tp_call @@ -447,7 +462,14 @@ proxy_checkref(PyWeakReference *proxy) UNWRAP(v); \ if (w != NULL) \ UNWRAP(w); \ - return generic(proxy, v, w); \ + Py_INCREF(proxy); \ + Py_INCREF(v); \ + Py_XINCREF(w); \ + PyObject* res = generic(proxy, v, w); \ + Py_DECREF(proxy); \ + Py_DECREF(v); \ + Py_XDECREF(w); \ + return res; \ } #define WRAP_METHOD(method, special) \ @@ -455,7 +477,10 @@ proxy_checkref(PyWeakReference *proxy) method(PyObject *proxy, PyObject *Py_UNUSED(ignored)) { \ _Py_IDENTIFIER(special); \ UNWRAP(proxy); \ - return _PyObject_CallMethodId(proxy, &PyId_##special, NULL); \ + Py_INCREF(proxy); \ + PyObject* res = _PyObject_CallMethodId(proxy, &PyId_##special, NULL); \ + Py_DECREF(proxy); \ + return res; \ } @@ -481,7 +506,11 @@ proxy_setattr(PyWeakReference *proxy, PyObject *name, PyObject *value) { if (!proxy_checkref(proxy)) return -1; - return PyObject_SetAttr(PyWeakref_GET_OBJECT(proxy), name, value); + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + int res = PyObject_SetAttr(obj, name, value); + Py_DECREF(obj); + return res; } static PyObject * @@ -532,9 +561,13 @@ static int proxy_bool(PyWeakReference *proxy) { PyObject *o = PyWeakref_GET_OBJECT(proxy); - if (!proxy_checkref(proxy)) + if (!proxy_checkref(proxy)) { return -1; - return PyObject_IsTrue(o); + } + Py_INCREF(o); + int res = PyObject_IsTrue(o); + Py_DECREF(o); + return res; } static void @@ -553,9 +586,13 @@ proxy_contains(PyWeakReference *proxy, PyObject *value) { if (!proxy_checkref(proxy)) return -1; - return PySequence_Contains(PyWeakref_GET_OBJECT(proxy), value); -} + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + int res = PySequence_Contains(obj, value); + Py_DECREF(obj); + return res; +} /* mapping slots */ @@ -564,7 +601,12 @@ proxy_length(PyWeakReference *proxy) { if (!proxy_checkref(proxy)) return -1; - return PyObject_Length(PyWeakref_GET_OBJECT(proxy)); + + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + Py_ssize_t res = PyObject_Length(obj); + Py_DECREF(obj); + return res; } WRAP_BINARY(proxy_getitem, PyObject_GetItem) @@ -575,10 +617,16 @@ proxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value) if (!proxy_checkref(proxy)) return -1; - if (value == NULL) - return PyObject_DelItem(PyWeakref_GET_OBJECT(proxy), key); - else - return PyObject_SetItem(PyWeakref_GET_OBJECT(proxy), key, value); + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + int res; + if (value == NULL) { + res = PyObject_DelItem(obj, key); + } else { + res = PyObject_SetItem(obj, key, value); + } + Py_DECREF(obj); + return res; } /* iterator slots */ @@ -588,7 +636,11 @@ proxy_iter(PyWeakReference *proxy) { if (!proxy_checkref(proxy)) return NULL; - return PyObject_GetIter(PyWeakref_GET_OBJECT(proxy)); + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + PyObject* res = PyObject_GetIter(obj); + Py_DECREF(obj); + return res; } static PyObject * @@ -596,7 +648,12 @@ proxy_iternext(PyWeakReference *proxy) { if (!proxy_checkref(proxy)) return NULL; - return PyIter_Next(PyWeakref_GET_OBJECT(proxy)); + + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + PyObject* res = PyIter_Next(obj); + Py_DECREF(obj); + return res; } diff --git a/PC/bdist_wininst/install.c b/PC/bdist_wininst/install.c index 6d01ad5c2d50e7..72d9837fe4f7f0 100644 --- a/PC/bdist_wininst/install.c +++ b/PC/bdist_wininst/install.c @@ -938,7 +938,8 @@ static BOOL SystemError(int error, char *msg) LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), diff --git a/PC/clinic/_testconsole.c.h b/PC/clinic/_testconsole.c.h index a37d1235a02a9e..cf5e4ee09063aa 100644 --- a/PC/clinic/_testconsole.c.h +++ b/PC/clinic/_testconsole.c.h @@ -33,7 +33,7 @@ _testconsole_write_input(PyObject *module, PyObject *const *args, Py_ssize_t nar } file = args[0]; if (!PyBytes_Check(args[1])) { - _PyArg_BadArgument("write_input", 2, "bytes", args[1]); + _PyArg_BadArgument("write_input", "argument 's'", "bytes", args[1]); goto exit; } s = (PyBytesObject *)args[1]; @@ -88,4 +88,4 @@ _testconsole_read_output(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef _TESTCONSOLE_READ_OUTPUT_METHODDEF #define _TESTCONSOLE_READ_OUTPUT_METHODDEF #endif /* !defined(_TESTCONSOLE_READ_OUTPUT_METHODDEF) */ -/*[clinic end generated code: output=ef452d5fb9287fc2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dd8b093a91b62753 input=a9049054013a1b77]*/ diff --git a/PC/clinic/msvcrtmodule.c.h b/PC/clinic/msvcrtmodule.c.h index d8e77d5f328dda..180c3e5fc54a7a 100644 --- a/PC/clinic/msvcrtmodule.c.h +++ b/PC/clinic/msvcrtmodule.c.h @@ -375,7 +375,7 @@ msvcrt_putch(PyObject *module, PyObject *arg) char_value = PyByteArray_AS_STRING(arg)[0]; } else { - _PyArg_BadArgument("putch", 0, "a byte string of length 1", arg); + _PyArg_BadArgument("putch", "argument", "a byte string of length 1", arg); goto exit; } return_value = msvcrt_putch_impl(module, char_value); @@ -403,14 +403,14 @@ msvcrt_putwch(PyObject *module, PyObject *arg) int unicode_char; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("putwch", 0, "a unicode character", arg); + _PyArg_BadArgument("putwch", "argument", "a unicode character", arg); goto exit; } if (PyUnicode_READY(arg)) { goto exit; } if (PyUnicode_GET_LENGTH(arg) != 1) { - _PyArg_BadArgument("putwch", 0, "a unicode character", arg); + _PyArg_BadArgument("putwch", "argument", "a unicode character", arg); goto exit; } unicode_char = PyUnicode_READ_CHAR(arg, 0); @@ -449,7 +449,7 @@ msvcrt_ungetch(PyObject *module, PyObject *arg) char_value = PyByteArray_AS_STRING(arg)[0]; } else { - _PyArg_BadArgument("ungetch", 0, "a byte string of length 1", arg); + _PyArg_BadArgument("ungetch", "argument", "a byte string of length 1", arg); goto exit; } return_value = msvcrt_ungetch_impl(module, char_value); @@ -477,14 +477,14 @@ msvcrt_ungetwch(PyObject *module, PyObject *arg) int unicode_char; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("ungetwch", 0, "a unicode character", arg); + _PyArg_BadArgument("ungetwch", "argument", "a unicode character", arg); goto exit; } if (PyUnicode_READY(arg)) { goto exit; } if (PyUnicode_GET_LENGTH(arg) != 1) { - _PyArg_BadArgument("ungetwch", 0, "a unicode character", arg); + _PyArg_BadArgument("ungetwch", "argument", "a unicode character", arg); goto exit; } unicode_char = PyUnicode_READ_CHAR(arg, 0); @@ -679,4 +679,4 @@ msvcrt_SetErrorMode(PyObject *module, PyObject *arg) #ifndef MSVCRT_SET_ERROR_MODE_METHODDEF #define MSVCRT_SET_ERROR_MODE_METHODDEF #endif /* !defined(MSVCRT_SET_ERROR_MODE_METHODDEF) */ -/*[clinic end generated code: output=816bc4f993893cea input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7cc6ffaf64f268f7 input=a9049054013a1b77]*/ diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 50210250ed1967..b7af1855ac5456 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -1029,7 +1029,7 @@ PyDoc_STRVAR(winreg_DisableReflectionKey__doc__, " key\n" " An already open key, or any one of the predefined HKEY_* constants.\n" "\n" -"Will generally raise NotImplemented if executed on a 32bit OS.\n" +"Will generally raise NotImplementedError if executed on a 32bit OS.\n" "\n" "If the key is not on the reflection list, the function succeeds but has\n" "no effect. Disabling reflection for a key does not affect reflection\n" @@ -1065,7 +1065,7 @@ PyDoc_STRVAR(winreg_EnableReflectionKey__doc__, " key\n" " An already open key, or any one of the predefined HKEY_* constants.\n" "\n" -"Will generally raise NotImplemented if executed on a 32bit OS.\n" +"Will generally raise NotImplementedError if executed on a 32bit OS.\n" "Restoring reflection for a key does not affect reflection of any\n" "subkeys."); @@ -1099,7 +1099,7 @@ PyDoc_STRVAR(winreg_QueryReflectionKey__doc__, " key\n" " An already open key, or any one of the predefined HKEY_* constants.\n" "\n" -"Will generally raise NotImplemented if executed on a 32bit OS."); +"Will generally raise NotImplementedError if executed on a 32bit OS."); #define WINREG_QUERYREFLECTIONKEY_METHODDEF \ {"QueryReflectionKey", (PyCFunction)winreg_QueryReflectionKey, METH_O, winreg_QueryReflectionKey__doc__}, @@ -1121,4 +1121,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=1204d20c543b5b4a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=015afbbd690eb59d input=a9049054013a1b77]*/ diff --git a/PC/config.c b/PC/config.c index 6f34962bd72d4f..8eaeb31c9b934b 100644 --- a/PC/config.c +++ b/PC/config.c @@ -23,6 +23,7 @@ extern PyObject* PyInit__sha1(void); extern PyObject* PyInit__sha256(void); extern PyObject* PyInit__sha512(void); extern PyObject* PyInit__sha3(void); +extern PyObject* PyInit__statistics(void); extern PyObject* PyInit__blake2(void); extern PyObject* PyInit_time(void); extern PyObject* PyInit__thread(void); @@ -103,6 +104,7 @@ struct _inittab _PyImport_Inittab[] = { {"_blake2", PyInit__blake2}, {"time", PyInit_time}, {"_thread", PyInit__thread}, + {"_statistics", PyInit__statistics}, #ifdef WIN32 {"msvcrt", PyInit_msvcrt}, {"_locale", PyInit__locale}, diff --git a/Tools/msi/exe/crtlicense.txt b/PC/crtlicense.txt similarity index 100% rename from Tools/msi/exe/crtlicense.txt rename to PC/crtlicense.txt diff --git a/PC/errmap.h b/PC/errmap.h index 985f673a4649c8..a7489ab75c6561 100644 --- a/PC/errmap.h +++ b/PC/errmap.h @@ -1,80 +1,140 @@ -/* Generated file. Do not edit. */ -int winerror_to_errno(int winerror) +int +winerror_to_errno(int winerror) { - switch(winerror) { - case 2: return 2; - case 3: return 2; - case 4: return 24; - case 5: return 13; - case 6: return 9; - case 7: return 12; - case 8: return 12; - case 9: return 12; - case 10: return 7; - case 11: return 8; - case 15: return 2; - case 16: return 13; - case 17: return 18; - case 18: return 2; - case 19: return 13; - case 20: return 13; - case 21: return 13; - case 22: return 13; - case 23: return 13; - case 24: return 13; - case 25: return 13; - case 26: return 13; - case 27: return 13; - case 28: return 13; - case 29: return 13; - case 30: return 13; - case 31: return 13; - case 32: return 13; - case 33: return 13; - case 34: return 13; - case 35: return 13; - case 36: return 13; - case 53: return 2; - case 65: return 13; - case 67: return 2; - case 80: return 17; - case 82: return 13; - case 83: return 13; - case 89: return 11; - case 108: return 13; - case 109: return 32; - case 112: return 28; - case 114: return 9; - case 128: return 10; - case 129: return 10; - case 130: return 9; - case 132: return 13; - case 145: return 41; - case 158: return 13; - case 161: return 2; - case 164: return 11; - case 167: return 13; - case 183: return 17; - case 188: return 8; - case 189: return 8; - case 190: return 8; - case 191: return 8; - case 192: return 8; - case 193: return 8; - case 194: return 8; - case 195: return 8; - case 196: return 8; - case 197: return 8; - case 198: return 8; - case 199: return 8; - case 200: return 8; - case 201: return 8; - case 202: return 8; - case 206: return 2; - case 215: return 11; - case 232: return 32; - case 267: return 20; - case 1816: return 12; - default: return EINVAL; + // Unwrap FACILITY_WIN32 HRESULT errors. + if ((winerror & 0xFFFF0000) == 0x80070000) { + winerror &= 0x0000FFFF; + } + + // Winsock error codes (10000-11999) are errno values. + if (winerror >= 10000 && winerror < 12000) { + switch (winerror) { + case WSAEINTR: + case WSAEBADF: + case WSAEACCES: + case WSAEFAULT: + case WSAEINVAL: + case WSAEMFILE: + // Winsock definitions of errno values. See WinSock2.h + return winerror - 10000; + default: + return winerror; + } + } + + switch (winerror) { + case ERROR_FILE_NOT_FOUND: // 2 + case ERROR_PATH_NOT_FOUND: // 3 + case ERROR_INVALID_DRIVE: // 15 + case ERROR_NO_MORE_FILES: // 18 + case ERROR_BAD_NETPATH: // 53 + case ERROR_BAD_NET_NAME: // 67 + case ERROR_BAD_PATHNAME: // 161 + case ERROR_FILENAME_EXCED_RANGE: // 206 + return ENOENT; + + case ERROR_BAD_ENVIRONMENT: // 10 + return E2BIG; + + case ERROR_BAD_FORMAT: // 11 + case ERROR_INVALID_STARTING_CODESEG: // 188 + case ERROR_INVALID_STACKSEG: // 189 + case ERROR_INVALID_MODULETYPE: // 190 + case ERROR_INVALID_EXE_SIGNATURE: // 191 + case ERROR_EXE_MARKED_INVALID: // 192 + case ERROR_BAD_EXE_FORMAT: // 193 + case ERROR_ITERATED_DATA_EXCEEDS_64k: // 194 + case ERROR_INVALID_MINALLOCSIZE: // 195 + case ERROR_DYNLINK_FROM_INVALID_RING: // 196 + case ERROR_IOPL_NOT_ENABLED: // 197 + case ERROR_INVALID_SEGDPL: // 198 + case ERROR_AUTODATASEG_EXCEEDS_64k: // 199 + case ERROR_RING2SEG_MUST_BE_MOVABLE: // 200 + case ERROR_RELOC_CHAIN_XEEDS_SEGLIM: // 201 + case ERROR_INFLOOP_IN_RELOC_CHAIN: // 202 + return ENOEXEC; + + case ERROR_INVALID_HANDLE: // 6 + case ERROR_INVALID_TARGET_HANDLE: // 114 + case ERROR_DIRECT_ACCESS_HANDLE: // 130 + return EBADF; + + case ERROR_WAIT_NO_CHILDREN: // 128 + case ERROR_CHILD_NOT_COMPLETE: // 129 + return ECHILD; + + case ERROR_NO_PROC_SLOTS: // 89 + case ERROR_MAX_THRDS_REACHED: // 164 + case ERROR_NESTING_NOT_ALLOWED: // 215 + return EAGAIN; + + case ERROR_ARENA_TRASHED: // 7 + case ERROR_NOT_ENOUGH_MEMORY: // 8 + case ERROR_INVALID_BLOCK: // 9 + case ERROR_NOT_ENOUGH_QUOTA: // 1816 + return ENOMEM; + + case ERROR_ACCESS_DENIED: // 5 + case ERROR_CURRENT_DIRECTORY: // 16 + case ERROR_WRITE_PROTECT: // 19 + case ERROR_BAD_UNIT: // 20 + case ERROR_NOT_READY: // 21 + case ERROR_BAD_COMMAND: // 22 + case ERROR_CRC: // 23 + case ERROR_BAD_LENGTH: // 24 + case ERROR_SEEK: // 25 + case ERROR_NOT_DOS_DISK: // 26 + case ERROR_SECTOR_NOT_FOUND: // 27 + case ERROR_OUT_OF_PAPER: // 28 + case ERROR_WRITE_FAULT: // 29 + case ERROR_READ_FAULT: // 30 + case ERROR_GEN_FAILURE: // 31 + case ERROR_SHARING_VIOLATION: // 32 + case ERROR_LOCK_VIOLATION: // 33 + case ERROR_WRONG_DISK: // 34 + case ERROR_SHARING_BUFFER_EXCEEDED: // 36 + case ERROR_NETWORK_ACCESS_DENIED: // 65 + case ERROR_CANNOT_MAKE: // 82 + case ERROR_FAIL_I24: // 83 + case ERROR_DRIVE_LOCKED: // 108 + case ERROR_SEEK_ON_DEVICE: // 132 + case ERROR_NOT_LOCKED: // 158 + case ERROR_LOCK_FAILED: // 167 + case 35: // 35 (undefined) + return EACCES; + + case ERROR_FILE_EXISTS: // 80 + case ERROR_ALREADY_EXISTS: // 183 + return EEXIST; + + case ERROR_NOT_SAME_DEVICE: // 17 + return EXDEV; + + case ERROR_DIRECTORY: // 267 (bpo-12802) + return ENOTDIR; + + case ERROR_TOO_MANY_OPEN_FILES: // 4 + return EMFILE; + + case ERROR_DISK_FULL: // 112 + return ENOSPC; + + case ERROR_BROKEN_PIPE: // 109 + case ERROR_NO_DATA: // 232 (bpo-13063) + return EPIPE; + + case ERROR_DIR_NOT_EMPTY: // 145 + return ENOTEMPTY; + + case ERROR_NO_UNICODE_TRANSLATION: // 1113 + return EILSEQ; + + case ERROR_INVALID_FUNCTION: // 1 + case ERROR_INVALID_ACCESS: // 12 + case ERROR_INVALID_DATA: // 13 + case ERROR_INVALID_PARAMETER: // 87 + case ERROR_NEGATIVE_SEEK: // 131 + default: + return EINVAL; } } diff --git a/PC/generrmap.c b/PC/generrmap.c deleted file mode 100644 index 953344c0d79597..00000000000000 --- a/PC/generrmap.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include -#include -#include -#include - -/* Extract the mapping of Win32 error codes to errno */ - -int main() -{ - int i; - _setmode(fileno(stdout), O_BINARY); - printf("/* Generated file. Do not edit. */\n"); - printf("int winerror_to_errno(int winerror)\n"); - printf("{\n switch(winerror) {\n"); - for(i=1; i < 65000; i++) { - _dosmaperr(i); - if (errno == EINVAL) { - /* Issue #12802 */ - if (i == ERROR_DIRECTORY) - errno = ENOTDIR; - /* Issue #13063 */ - else if (i == ERROR_NO_DATA) - errno = EPIPE; - else - continue; - } - printf(" case %d: return %d;\n", i, errno); - } - printf(" default: return EINVAL;\n"); - printf(" }\n}\n"); -} diff --git a/PC/getpathp.c b/PC/getpathp.c index e86cf13a4910ac..04f24d986f667c 100644 --- a/PC/getpathp.c +++ b/PC/getpathp.c @@ -115,19 +115,24 @@ */ #ifndef LANDMARK -#define LANDMARK L"lib\\os.py" +# define LANDMARK L"lib\\os.py" #endif +#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\PythonPath" */ + /* 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 */ - wchar_t argv0_path[MAXPATHLEN+1]; - wchar_t zip_path[MAXPATHLEN+1]; + wchar_t *dll_path; + + const wchar_t *pythonpath_env; } PyCalculatePath; @@ -272,7 +277,10 @@ typedef HRESULT(__stdcall *PPathCchCanonicalizeEx) (PWSTR pszPathOut, size_t cch PCWSTR pszPathIn, unsigned long dwFlags); static PPathCchCanonicalizeEx _PathCchCanonicalizeEx; -static PyStatus canonicalize(wchar_t *buffer, const wchar_t *path) +/* 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(); @@ -291,12 +299,12 @@ static PyStatus canonicalize(wchar_t *buffer, const wchar_t *path) if (_PathCchCanonicalizeEx) { if (FAILED(_PathCchCanonicalizeEx(buffer, MAXPATHLEN + 1, path, 0))) { - return _PyStatus_ERR("buffer overflow in getpathp.c's canonicalize()"); + return INIT_ERR_BUFFER_OVERFLOW(); } } else { if (!PathCanonicalizeW(buffer, path)) { - return _PyStatus_ERR("buffer overflow in getpathp.c's canonicalize()"); + return INIT_ERR_BUFFER_OVERFLOW(); } } return _PyStatus_OK(); @@ -307,20 +315,18 @@ static PyStatus canonicalize(wchar_t *buffer, const wchar_t *path) 'prefix' is null terminated in bounds. join() ensures 'landmark' can not overflow prefix if too long. */ static int -gotlandmark(wchar_t *prefix, const wchar_t *landmark) +gotlandmark(const wchar_t *prefix, const wchar_t *landmark) { - int ok; - Py_ssize_t n = wcsnlen_s(prefix, MAXPATHLEN); - - join(prefix, landmark); - ok = ismodule(prefix, FALSE); - prefix[n] = '\0'; - return ok; + wchar_t filename[MAXPATHLEN+1]; + memset(filename, 0, sizeof(filename)); + wcscpy_s(filename, Py_ARRAY_LENGTH(filename), prefix); + join(filename, landmark); + return ismodule(filename, FALSE); } /* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd. - assumption provided by only caller, calculate_path_impl() */ + assumption provided by only caller, calculate_path() */ static int search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path, const wchar_t *landmark) { @@ -530,37 +536,72 @@ _Py_GetDLLPath(void) static PyStatus -get_program_full_path(const PyConfig *config, - PyCalculatePath *calculate, _PyPathConfig *pathconfig) +get_program_full_path(_PyPathConfig *pathconfig) { + PyStatus status; const wchar_t *pyvenv_launcher; wchar_t program_full_path[MAXPATHLEN+1]; memset(program_full_path, 0, sizeof(program_full_path)); + if (!GetModuleFileNameW(NULL, program_full_path, MAXPATHLEN)) { + /* GetModuleFileName should never fail when passed NULL */ + return _PyStatus_ERR("Cannot determine program path"); + } + /* The launcher may need to force the executable path to a * different environment, so override it here. */ pyvenv_launcher = _wgetenv(L"__PYVENV_LAUNCHER__"); if (pyvenv_launcher && pyvenv_launcher[0]) { + /* If overridden, preserve the original full path */ + if (pathconfig->base_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); - } else if (!GetModuleFileNameW(NULL, program_full_path, MAXPATHLEN)) { - /* GetModuleFileName should never fail when passed NULL */ - return _PyStatus_ERR("Cannot determine program path"); + /* bpo-35873: Clear the environment variable to avoid it being + * inherited by child processes. */ + _wputenv_s(L"__PYVENV_LAUNCHER__", L""); } - pathconfig->program_full_path = PyMem_RawMalloc( - sizeof(wchar_t) * (MAXPATHLEN + 1)); + 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(); + } - return canonicalize(pathconfig->program_full_path, - program_full_path); + status = canonicalize(pathconfig->program_full_path, + program_full_path); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + return _PyStatus_OK(); } -static int -read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path) +static PyStatus +read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path, + int *found) { - FILE *sp_file = _Py_wfopen(path, L"r"); + 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 0; + return _PyStatus_OK(); } wcscpy_s(prefix, MAXPATHLEN+1, path); @@ -571,15 +612,16 @@ read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path) size_t bufsiz = MAXPATHLEN; size_t prefixlen = wcslen(prefix); - wchar_t *buf = (wchar_t*)PyMem_RawMalloc(bufsiz * sizeof(wchar_t)); + buf = (wchar_t*)PyMem_RawMalloc(bufsiz * sizeof(wchar_t)); if (buf == NULL) { - goto error; + status = _PyStatus_NO_MEMORY(); + goto done; } buf[0] = '\0'; while (!feof(sp_file)) { char line[MAXPATHLEN + 1]; - char *p = fgets(line, MAXPATHLEN + 1, sp_file); + char *p = fgets(line, Py_ARRAY_LENGTH(line), sp_file); if (!p) { break; } @@ -598,13 +640,16 @@ read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path) continue; } else if (strncmp(line, "import ", 7) == 0) { - Py_FatalError("only 'import site' is supported in ._pth file"); + 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) { - goto error; + status = _PyStatus_NO_MEMORY(); + goto done; } wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, wline, wn + 1); wline[wn] = '\0'; @@ -615,8 +660,8 @@ read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path) wchar_t *tmp = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) * sizeof(wchar_t)); if (tmp == NULL) { - PyMem_RawFree(wline); - goto error; + status = _PyStatus_NO_MEMORY(); + goto done; } buf = tmp; } @@ -630,50 +675,56 @@ read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path) _Py_BEGIN_SUPPRESS_IPH result = wcscat_s(buf, bufsiz, prefix); _Py_END_SUPPRESS_IPH + if (result == EINVAL) { - Py_FatalError("invalid argument during ._pth processing"); + status = _PyStatus_ERR("invalid argument during ._pth processing"); + goto done; } else if (result == ERANGE) { - Py_FatalError("buffer overflow during ._pth processing"); + status = _PyStatus_ERR("buffer overflow during ._pth processing"); + goto done; } + wchar_t *b = &buf[usedsiz]; join(b, wline); PyMem_RawFree(wline); + wline = NULL; } - fclose(sp_file); - pathconfig->module_search_path = buf; - return 1; + 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; -error: +done: PyMem_RawFree(buf); + PyMem_RawFree(wline); fclose(sp_file); - return 0; -} - - -static void -calculate_init(PyCalculatePath *calculate, - const PyConfig *config) -{ - calculate->home = config->home; - calculate->path_env = _wgetenv(L"PATH"); + return status; } static int -get_pth_filename(wchar_t *spbuffer, _PyPathConfig *pathconfig) +get_pth_filename(PyCalculatePath *calculate, wchar_t *filename, + const _PyPathConfig *pathconfig) { - if (pathconfig->dll_path[0]) { - if (!change_ext(spbuffer, pathconfig->dll_path, L"._pth") && - exists(spbuffer)) + if (calculate->dll_path[0]) { + if (!change_ext(filename, calculate->dll_path, L"._pth") && + exists(filename)) { return 1; } } if (pathconfig->program_full_path[0]) { - if (!change_ext(spbuffer, pathconfig->program_full_path, L"._pth") && - exists(spbuffer)) + if (!change_ext(filename, pathconfig->program_full_path, L"._pth") && + exists(filename)) { return 1; } @@ -682,16 +733,17 @@ get_pth_filename(wchar_t *spbuffer, _PyPathConfig *pathconfig) } -static int -calculate_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix) +static PyStatus +calculate_pth_file(PyCalculatePath *calculate, _PyPathConfig *pathconfig, + wchar_t *prefix, int *found) { - wchar_t spbuffer[MAXPATHLEN+1]; + wchar_t filename[MAXPATHLEN+1]; - if (!get_pth_filename(spbuffer, pathconfig)) { - return 0; + if (!get_pth_filename(calculate, filename, pathconfig)) { + return _PyStatus_OK(); } - return read_pth_file(pathconfig, prefix, spbuffer); + return read_pth_file(pathconfig, prefix, filename, found); } @@ -700,54 +752,55 @@ calculate_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix) If found, open it for use when searching for prefixes. */ static void -calculate_pyvenv_file(PyCalculatePath *calculate) +calculate_pyvenv_file(PyCalculatePath *calculate, + wchar_t *argv0_path, size_t argv0_path_len) { - wchar_t envbuffer[MAXPATHLEN+1]; + wchar_t filename[MAXPATHLEN+1]; const wchar_t *env_cfg = L"pyvenv.cfg"; - wcscpy_s(envbuffer, MAXPATHLEN+1, calculate->argv0_path); - join(envbuffer, env_cfg); + /* Filename: / "pyvenv.cfg" */ + wcscpy_s(filename, MAXPATHLEN+1, argv0_path); + join(filename, env_cfg); - FILE *env_file = _Py_wfopen(envbuffer, L"r"); + FILE *env_file = _Py_wfopen(filename, L"r"); if (env_file == NULL) { errno = 0; - reduce(envbuffer); - reduce(envbuffer); - join(envbuffer, env_cfg); + /* Filename: / "pyvenv.cfg" */ + reduce(filename); + reduce(filename); + join(filename, env_cfg); - env_file = _Py_wfopen(envbuffer, L"r"); + env_file = _Py_wfopen(filename, L"r"); if (env_file == NULL) { errno = 0; + return; } } - if (env_file == NULL) { - return; - } - /* Look for a 'home' variable and set argv0_path to it, if found */ - wchar_t tmpbuffer[MAXPATHLEN+1]; - if (_Py_FindEnvConfigValue(env_file, L"home", tmpbuffer, MAXPATHLEN)) { - wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, tmpbuffer); + wchar_t home[MAXPATHLEN+1]; + if (_Py_FindEnvConfigValue(env_file, L"home", + home, Py_ARRAY_LENGTH(home))) { + wcscpy_s(argv0_path, argv0_path_len, home); } fclose(env_file); } -#define INIT_ERR_BUFFER_OVERFLOW() _PyStatus_ERR("buffer overflow") - - static void -calculate_home_prefix(PyCalculatePath *calculate, wchar_t *prefix) +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 (calculate->zip_path[0] && exists(calculate->zip_path)) { - wcscpy_s(prefix, MAXPATHLEN+1, calculate->zip_path); + 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, calculate->argv0_path, LANDMARK)) { + else if (search_for_prefix(prefix, argv0_path, LANDMARK)) { calculate->home = prefix; } else { @@ -761,9 +814,11 @@ calculate_home_prefix(PyCalculatePath *calculate, wchar_t *prefix) static PyStatus -calculate_module_search_path(const PyConfig *config, - PyCalculatePath *calculate, _PyPathConfig *pathconfig, - wchar_t *prefix) +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 @@ -772,7 +827,7 @@ calculate_module_search_path(const PyConfig *config, #endif /* We only use the default relative PYTHONPATH if we haven't anything better to use! */ - int skipdefault = (config->pythonpath_env != NULL || + int skipdefault = (calculate->pythonpath_env != NULL || calculate->home != NULL || calculate->machine_path != NULL || calculate->user_path != NULL); @@ -803,45 +858,35 @@ calculate_module_search_path(const PyConfig *config, bufsz *= wcslen(calculate->home); } bufsz += wcslen(PYTHONPATH) + 1; - bufsz += wcslen(calculate->argv0_path) + 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(calculate->zip_path) + 1; - if (config->pythonpath_env != NULL) { - bufsz += wcslen(config->pythonpath_env) + 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) { - /* We can't exit, so print a warning and limp along */ - fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n"); - if (config->pythonpath_env) { - fprintf(stderr, "Using environment $PYTHONPATH.\n"); - pathconfig->module_search_path = config->pythonpath_env; - } - else { - fprintf(stderr, "Using default static path.\n"); - pathconfig->module_search_path = PYTHONPATH; - } - return _PyStatus_OK(); + return _PyStatus_NO_MEMORY(); } start_buf = buf; - if (config->pythonpath_env) { + if (calculate->pythonpath_env) { if (wcscpy_s(buf, bufsz - (buf - start_buf), - config->pythonpath_env)) { + calculate->pythonpath_env)) { return INIT_ERR_BUFFER_OVERFLOW(); } buf = wcschr(buf, L'\0'); *buf++ = DELIM; } - if (calculate->zip_path[0]) { - if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->zip_path)) { + if (zip_path[0]) { + if (wcscpy_s(buf, bufsz - (buf - start_buf), zip_path)) { return INIT_ERR_BUFFER_OVERFLOW(); } buf = wcschr(buf, L'\0'); @@ -898,8 +943,8 @@ calculate_module_search_path(const PyConfig *config, p = q+1; } } - if (calculate->argv0_path) { - wcscpy(buf, calculate->argv0_path); + if (argv0_path) { + wcscpy(buf, argv0_path); buf = wcschr(buf, L'\0'); *buf++ = DELIM; } @@ -947,59 +992,87 @@ calculate_module_search_path(const PyConfig *config, static PyStatus -calculate_path_impl(const PyConfig *config, - PyCalculatePath *calculate, _PyPathConfig *pathconfig) +calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) { PyStatus status; - assert(pathconfig->dll_path == NULL); - - pathconfig->dll_path = _Py_GetDLLPath(); - if (pathconfig->dll_path == NULL) { - return _PyStatus_NO_MEMORY(); - } - - status = get_program_full_path(config, calculate, pathconfig); + status = get_program_full_path(pathconfig); if (_PyStatus_EXCEPTION(status)) { return status; } /* program_full_path guaranteed \0 terminated in MAXPATH+1 bytes. */ - wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, pathconfig->program_full_path); - reduce(calculate->argv0_path); + 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 */ - if (calculate_pth_file(pathconfig, prefix)) { + int pth_found = 0; + status = calculate_pth_file(calculate, pathconfig, prefix, &pth_found); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + if (pth_found) { goto done; } - calculate_pyvenv_file(calculate); + calculate_pyvenv_file(calculate, argv0_path, Py_ARRAY_LENGTH(argv0_path)); /* Calculate zip archive path from DLL or exe path */ - change_ext(calculate->zip_path, - pathconfig->dll_path[0] ? pathconfig->dll_path : pathconfig->program_full_path, + wchar_t zip_path[MAXPATHLEN+1]; + memset(zip_path, 0, sizeof(zip_path)); + + change_ext(zip_path, + calculate->dll_path[0] ? calculate->dll_path : pathconfig->program_full_path, L".zip"); - calculate_home_prefix(calculate, prefix); + calculate_home_prefix(calculate, argv0_path, zip_path, prefix); - status = calculate_module_search_path(config, calculate, pathconfig, prefix); - if (_PyStatus_EXCEPTION(status)) { - return status; + 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: - pathconfig->prefix = _PyMem_RawWcsdup(prefix); if (pathconfig->prefix == NULL) { - return _PyStatus_NO_MEMORY(); + pathconfig->prefix = _PyMem_RawWcsdup(prefix); + if (pathconfig->prefix == NULL) { + return _PyStatus_NO_MEMORY(); + } } - pathconfig->exec_prefix = _PyMem_RawWcsdup(prefix); 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->dll_path = _Py_GetDLLPath(); + if (calculate->dll_path == NULL) { return _PyStatus_NO_MEMORY(); } + calculate->pythonpath_env = config->pythonpath_env; + return _PyStatus_OK(); } @@ -1009,23 +1082,51 @@ calculate_free(PyCalculatePath *calculate) { PyMem_RawFree(calculate->machine_path); PyMem_RawFree(calculate->user_path); + PyMem_RawFree(calculate->dll_path); } +/* Calculate the Python path configuration. + + Inputs: + + - PyConfig.pythonpath_env: PYTHONPATH environment variable + - _PyPathConfig.home: Py_SetPythonHome() or PYTHONHOME environment variable + - DLL path: _Py_GetDLLPath() + - 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)); - calculate_init(&calculate, config); - - PyStatus status = calculate_path_impl(config, &calculate, pathconfig); + status = calculate_init(&calculate, pathconfig, config); if (_PyStatus_EXCEPTION(status)) { goto done; } - status = _PyStatus_OK(); + status = calculate_path(&calculate, pathconfig); done: calculate_free(&calculate); @@ -1053,7 +1154,12 @@ _Py_CheckPython3(void) /* If there is a python3.dll next to the python3y.dll, assume this is a build tree; use that DLL */ - wcscpy(py3path, _Py_path_config.dll_path); + if (_Py_dll_path != NULL) { + wcscpy(py3path, _Py_dll_path); + } + else { + wcscpy(py3path, L""); + } s = wcsrchr(py3path, L'\\'); if (!s) { s = py3path; diff --git a/PC/icons/py.png b/PC/icons/py.png new file mode 100644 index 00000000000000..5c184e6a745f36 Binary files /dev/null and b/PC/icons/py.png differ diff --git a/PC/launcher.c b/PC/launcher.c index ed5ead329e460d..2749a4e7054671 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -141,6 +141,8 @@ static wchar_t * get_env(wchar_t * key) } #if defined(_DEBUG) +/* Do not define EXECUTABLEPATH_VALUE in debug builds as it'll + never point to the debug build. */ #if defined(_WINDOWS) #define PYTHON_EXECUTABLE L"pythonw_d.exe" @@ -154,20 +156,23 @@ static wchar_t * get_env(wchar_t * key) #if defined(_WINDOWS) #define PYTHON_EXECUTABLE L"pythonw.exe" +#define EXECUTABLEPATH_VALUE L"WindowedExecutablePath" #else #define PYTHON_EXECUTABLE L"python.exe" +#define EXECUTABLEPATH_VALUE L"ExecutablePath" #endif #endif -#define MAX_VERSION_SIZE 4 +#define MAX_VERSION_SIZE 8 typedef struct { wchar_t version[MAX_VERSION_SIZE]; /* m.n */ int bits; /* 32 or 64 */ wchar_t executable[MAX_PATH]; + wchar_t exe_display[MAX_PATH]; } INSTALLED_PYTHON; /* @@ -185,10 +190,18 @@ static size_t num_installed_pythons = 0; * The version name can be longer than MAX_VERSION_SIZE, but will be * truncated to just X.Y for comparisons. */ -#define IP_BASE_SIZE 40 +#define IP_BASE_SIZE 80 #define IP_VERSION_SIZE 8 #define IP_SIZE (IP_BASE_SIZE + IP_VERSION_SIZE) #define CORE_PATH L"SOFTWARE\\Python\\PythonCore" +/* + * Installations from the Microsoft Store will set the same registry keys, + * but because of a limitation in Windows they cannot be enumerated normally + * (unless you have no other Python installations... which is probably false + * because that's the most likely way to get this launcher!) + * This key is under HKEY_LOCAL_MACHINE + */ +#define LOOKASIDE_PATH L"SOFTWARE\\Microsoft\\AppModel\\Lookaside\\user\\Software\\Python\\PythonCore" static wchar_t * location_checks[] = { L"\\", @@ -201,7 +214,7 @@ static wchar_t * location_checks[] = { }; static INSTALLED_PYTHON * -find_existing_python(wchar_t * path) +find_existing_python(const wchar_t * path) { INSTALLED_PYTHON * result = NULL; size_t i; @@ -216,15 +229,32 @@ find_existing_python(wchar_t * path) return result; } +static INSTALLED_PYTHON * +find_existing_python2(int bits, const wchar_t * version) +{ + INSTALLED_PYTHON * result = NULL; + size_t i; + INSTALLED_PYTHON * ip; + + for (i = 0, ip = installed_pythons; i < num_installed_pythons; i++, ip++) { + if (bits == ip->bits && _wcsicmp(version, ip->version) == 0) { + result = ip; + break; + } + } + return result; +} + static void -locate_pythons_for_key(HKEY root, REGSAM flags) +_locate_pythons_for_key(HKEY root, LPCWSTR subkey, REGSAM flags, int bits, + int display_name_only) { HKEY core_root, ip_key; - LSTATUS status = RegOpenKeyExW(root, CORE_PATH, 0, flags, &core_root); + LSTATUS status = RegOpenKeyExW(root, subkey, 0, flags, &core_root); wchar_t message[MSGSIZE]; DWORD i; size_t n; - BOOL ok; + BOOL ok, append_name; DWORD type, data_size, attrs; INSTALLED_PYTHON * ip, * pip; wchar_t ip_version[IP_VERSION_SIZE]; @@ -252,8 +282,16 @@ locate_pythons_for_key(HKEY root, REGSAM flags) else { wcsncpy_s(ip->version, MAX_VERSION_SIZE, ip_version, MAX_VERSION_SIZE-1); + /* Still treating version as "x.y" rather than sys.winver + * When PEP 514 tags are properly used, we shouldn't need + * to strip this off here. + */ + check = wcsrchr(ip->version, L'-'); + if (check && !wcscmp(check, L"-32")) { + *check = L'\0'; + } _snwprintf_s(ip_path, IP_SIZE, _TRUNCATE, - L"%ls\\%ls\\InstallPath", CORE_PATH, ip_version); + L"%ls\\%ls\\InstallPath", subkey, ip_version); status = RegOpenKeyExW(root, ip_path, 0, flags, &ip_key); if (status != ERROR_SUCCESS) { winerror(status, message, MSGSIZE); @@ -262,42 +300,61 @@ locate_pythons_for_key(HKEY root, REGSAM flags) continue; } data_size = sizeof(ip->executable) - 1; - status = RegQueryValueExW(ip_key, NULL, NULL, &type, + append_name = FALSE; +#ifdef EXECUTABLEPATH_VALUE + status = RegQueryValueExW(ip_key, EXECUTABLEPATH_VALUE, NULL, &type, (LPBYTE)ip->executable, &data_size); +#else + status = ERROR_FILE_NOT_FOUND; /* actual error doesn't matter */ +#endif + if (status != ERROR_SUCCESS || type != REG_SZ || !data_size) { + append_name = TRUE; + data_size = sizeof(ip->executable) - 1; + status = RegQueryValueExW(ip_key, NULL, NULL, &type, + (LPBYTE)ip->executable, &data_size); + if (status != ERROR_SUCCESS) { + winerror(status, message, MSGSIZE); + debug(L"%ls\\%ls: %ls\n", key_name, ip_path, message); + RegCloseKey(ip_key); + continue; + } + } RegCloseKey(ip_key); - if (status != ERROR_SUCCESS) { - winerror(status, message, MSGSIZE); - debug(L"%ls\\%ls: %ls\n", key_name, ip_path, message); + if (type != REG_SZ) { continue; } - if (type == REG_SZ) { - data_size = data_size / sizeof(wchar_t) - 1; /* for NUL */ - if (ip->executable[data_size - 1] == L'\\') - --data_size; /* reg value ended in a backslash */ - /* ip->executable is data_size long */ - for (checkp = location_checks; *checkp; ++checkp) { - check = *checkp; + + data_size = data_size / sizeof(wchar_t) - 1; /* for NUL */ + if (ip->executable[data_size - 1] == L'\\') + --data_size; /* reg value ended in a backslash */ + /* ip->executable is data_size long */ + for (checkp = location_checks; *checkp; ++checkp) { + check = *checkp; + if (append_name) { _snwprintf_s(&ip->executable[data_size], MAX_PATH - data_size, MAX_PATH - data_size, L"%ls%ls", check, PYTHON_EXECUTABLE); - attrs = GetFileAttributesW(ip->executable); - if (attrs == INVALID_FILE_ATTRIBUTES) { - winerror(GetLastError(), message, MSGSIZE); - debug(L"locate_pythons_for_key: %ls: %ls", - ip->executable, message); - } - else if (attrs & FILE_ATTRIBUTE_DIRECTORY) { - debug(L"locate_pythons_for_key: '%ls' is a \ -directory\n", - ip->executable, attrs); - } - else if (find_existing_python(ip->executable)) { - debug(L"locate_pythons_for_key: %ls: already \ -found\n", ip->executable); - } - else { - /* check the executable type. */ + } + attrs = GetFileAttributesW(ip->executable); + if (attrs == INVALID_FILE_ATTRIBUTES) { + winerror(GetLastError(), message, MSGSIZE); + debug(L"locate_pythons_for_key: %ls: %ls", + ip->executable, message); + } + else if (attrs & FILE_ATTRIBUTE_DIRECTORY) { + debug(L"locate_pythons_for_key: '%ls' is a directory\n", + ip->executable, attrs); + } + else if (find_existing_python(ip->executable)) { + debug(L"locate_pythons_for_key: %ls: already found\n", + ip->executable); + } + else { + /* check the executable type. */ + if (bits) { + ip->bits = bits; + } else { ok = GetBinaryTypeW(ip->executable, &attrs); if (!ok) { debug(L"Failure getting binary type: %ls\n", @@ -310,32 +367,48 @@ found\n", ip->executable); ip->bits = 32; else ip->bits = 0; - if (ip->bits == 0) { - debug(L"locate_pythons_for_key: %ls: \ + } + } + if (ip->bits == 0) { + debug(L"locate_pythons_for_key: %ls: \ invalid binary type: %X\n", - ip->executable, attrs); + ip->executable, attrs); + } + else { + if (display_name_only) { + /* display just the executable name. This is + * primarily for the Store installs */ + const wchar_t *name = wcsrchr(ip->executable, L'\\'); + if (name) { + wcscpy_s(ip->exe_display, MAX_PATH, name+1); } - else { - if (wcschr(ip->executable, L' ') != NULL) { - /* has spaces, so quote */ - n = wcslen(ip->executable); - memmove(&ip->executable[1], - ip->executable, n * sizeof(wchar_t)); - ip->executable[0] = L'\"'; - ip->executable[n + 1] = L'\"'; - ip->executable[n + 2] = L'\0'; - } - debug(L"locate_pythons_for_key: %ls \ -is a %dbit executable\n", - ip->executable, ip->bits); - ++num_installed_pythons; - pip = ip++; - if (num_installed_pythons >= - MAX_INSTALLED_PYTHONS) - break; - /* Copy over the attributes for the next */ - *ip = *pip; + } + if (wcschr(ip->executable, L' ') != NULL) { + /* has spaces, so quote, and set original as + * the display name */ + if (!ip->exe_display[0]) { + wcscpy_s(ip->exe_display, MAX_PATH, ip->executable); } + n = wcslen(ip->executable); + memmove(&ip->executable[1], + ip->executable, n * sizeof(wchar_t)); + ip->executable[0] = L'\"'; + ip->executable[n + 1] = L'\"'; + ip->executable[n + 2] = L'\0'; + } + debug(L"locate_pythons_for_key: %ls \ +is a %dbit executable\n", + ip->executable, ip->bits); + if (find_existing_python2(ip->bits, ip->version)) { + debug(L"locate_pythons_for_key: %ls-%i: already \ +found\n", ip->version, ip->bits); + } + else { + ++num_installed_pythons; + pip = ip++; + if (num_installed_pythons >= + MAX_INSTALLED_PYTHONS) + break; } } } @@ -359,9 +432,63 @@ compare_pythons(const void * p1, const void * p2) return result; } +static void +locate_pythons_for_key(HKEY root, REGSAM flags) +{ + _locate_pythons_for_key(root, CORE_PATH, flags, 0, FALSE); +} + +static void +locate_store_pythons() +{ +#if defined(_M_X64) + /* 64bit process, so look in native registry */ + _locate_pythons_for_key(HKEY_LOCAL_MACHINE, LOOKASIDE_PATH, + KEY_READ, 64, TRUE); +#else + /* 32bit process, so check that we're on 64bit OS */ + BOOL f64 = FALSE; + if (IsWow64Process(GetCurrentProcess(), &f64) && f64) { + _locate_pythons_for_key(HKEY_LOCAL_MACHINE, LOOKASIDE_PATH, + KEY_READ | KEY_WOW64_64KEY, 64, TRUE); + } +#endif +} + +static void +locate_venv_python() +{ + static wchar_t venv_python[MAX_PATH]; + INSTALLED_PYTHON * ip; + wchar_t *virtual_env = get_env(L"VIRTUAL_ENV"); + DWORD attrs; + + /* Check for VIRTUAL_ENV environment variable */ + if (virtual_env == NULL || virtual_env[0] == L'\0') { + return; + } + + /* Check for a python executable in the venv */ + debug(L"Checking for Python executable in virtual env '%ls'\n", virtual_env); + _snwprintf_s(venv_python, MAX_PATH, _TRUNCATE, + L"%ls\\Scripts\\%ls", virtual_env, PYTHON_EXECUTABLE); + attrs = GetFileAttributesW(venv_python); + if (attrs == INVALID_FILE_ATTRIBUTES) { + debug(L"Python executable %ls missing from virtual env\n", venv_python); + return; + } + + ip = &installed_pythons[num_installed_pythons++]; + wcscpy_s(ip->executable, MAX_PATH, venv_python); + ip->bits = 0; + wcscpy_s(ip->version, MAX_VERSION_SIZE, L"venv"); +} + static void locate_all_pythons() { + /* venv Python is highest priority */ + locate_venv_python(); #if defined(_M_X64) /* If we are a 64bit process, first hit the 32bit keys. */ debug(L"locating Pythons in 32bit registry\n"); @@ -380,6 +507,8 @@ locate_all_pythons() debug(L"locating Pythons in native registry\n"); locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ); locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ); + /* Store-installed Python is lowest priority */ + locate_store_pythons(); qsort(installed_pythons, num_installed_pythons, sizeof(INSTALLED_PYTHON), compare_pythons); } @@ -416,31 +545,6 @@ find_python_by_version(wchar_t const * wanted_ver) } -static wchar_t * -find_python_by_venv() -{ - static wchar_t venv_python[MAX_PATH]; - wchar_t *virtual_env = get_env(L"VIRTUAL_ENV"); - DWORD attrs; - - /* Check for VIRTUAL_ENV environment variable */ - if (virtual_env == NULL || virtual_env[0] == L'\0') { - return NULL; - } - - /* Check for a python executable in the venv */ - debug(L"Checking for Python executable in virtual env '%ls'\n", virtual_env); - _snwprintf_s(venv_python, MAX_PATH, _TRUNCATE, - L"%ls\\Scripts\\%ls", virtual_env, PYTHON_EXECUTABLE); - attrs = GetFileAttributesW(venv_python); - if (attrs == INVALID_FILE_ATTRIBUTES) { - debug(L"Python executable %ls missing from virtual env\n", venv_python); - return NULL; - } - - return venv_python; -} - static wchar_t appdata_ini_path[MAX_PATH]; static wchar_t launcher_ini_path[MAX_PATH]; @@ -523,9 +627,12 @@ locate_python(wchar_t * wanted_ver, BOOL from_shebang) } else { *last_char = L'\0'; /* look for an overall default */ - configured_value = get_configured_value(config_key); - if (configured_value) - result = find_python_by_version(configured_value); + result = find_python_by_version(L"venv"); + if (result == NULL) { + configured_value = get_configured_value(config_key); + if (configured_value) + result = find_python_by_version(configured_value); + } /* Not found a value yet - try by major version. * If we're looking for an interpreter specified in a shebang line, * we want to try Python 2 first, then Python 3 (for Unix and backward @@ -1139,7 +1246,7 @@ static PYC_MAGIC magic_values[] = { { 3320, 3351, L"3.5" }, { 3360, 3379, L"3.6" }, { 3390, 3399, L"3.7" }, - { 3400, 3410, L"3.8" }, + { 3400, 3419, L"3.8" }, { 0 } }; @@ -1443,7 +1550,8 @@ show_python_list(wchar_t ** argv) INSTALLED_PYTHON * defpy = locate_python(L"", FALSE); size_t i = 0; wchar_t *p = argv[1]; - wchar_t *fmt = L"\n -%ls-%d"; /* print VER-BITS */ + wchar_t *ver_fmt = L"-%ls-%d"; + wchar_t *fmt = L"\n %ls"; wchar_t *defind = L" *"; /* Default indicator */ /* @@ -1452,8 +1560,8 @@ show_python_list(wchar_t ** argv) */ fwprintf(stderr, L"Installed Pythons found by %s Launcher for Windows", argv[0]); - if (!_wcsicmp(p, L"-0p") || !_wcsicmp(p, L"--list-paths")) /* Show path? */ - fmt = L"\n -%ls-%d\t%ls"; /* print VER-BITS path */ + if (!_wcsicmp(p, L"-0p") || !_wcsicmp(p, L"--list-paths")) + fmt = L"\n %-15ls%ls"; /* include path */ if (num_installed_pythons == 0) /* We have somehow got here without searching for pythons */ locate_all_pythons(); /* Find them, Populates installed_pythons */ @@ -1463,9 +1571,22 @@ show_python_list(wchar_t ** argv) else { for (i = 0; i < num_installed_pythons; i++, ip++) { - fwprintf(stdout, fmt, ip->version, ip->bits, ip->executable); + wchar_t version[BUFSIZ]; + if (wcscmp(ip->version, L"venv") == 0) { + wcscpy_s(version, BUFSIZ, L"(venv)"); + } + else { + swprintf_s(version, BUFSIZ, ver_fmt, ip->version, ip->bits); + } + + if (ip->exe_display[0]) { + fwprintf(stdout, fmt, version, ip->exe_display); + } + else { + fwprintf(stdout, fmt, version, ip->executable); + } /* If there is a default indicate it */ - if ((defpy != NULL) && !_wcsicmp(ip->executable, defpy->executable)) + if (defpy == ip) fwprintf(stderr, defind); } } @@ -1850,16 +1971,11 @@ installed, use -0 for available pythons", &p[1]); executable = NULL; /* Info call only */ } else { - /* Look for an active virtualenv */ - executable = find_python_by_venv(); - - /* If we didn't find one, look for the default Python */ - if (executable == NULL) { - ip = locate_python(L"", FALSE); - if (ip == NULL) - error(RC_NO_PYTHON, L"Can't find a default Python."); - executable = ip->executable; - } + /* look for the default Python */ + ip = locate_python(L"", FALSE); + if (ip == NULL) + error(RC_NO_PYTHON, L"Can't find a default Python."); + executable = ip->executable; } } if (executable != NULL) diff --git a/PC/layout/main.py b/PC/layout/main.py index 624033e721b73a..e59858196249af 100644 --- a/PC/layout/main.py +++ b/PC/layout/main.py @@ -31,6 +31,7 @@ from .support.options import * from .support.pip import * from .support.props import * +from .support.nuspec import * BDIST_WININST_FILES_ONLY = FileNameSet("wininst-*", "bdist_wininst.py") BDIST_WININST_STUB = "PC/layout/support/distutils.command.bdist_wininst.py" @@ -66,6 +67,7 @@ TOOLS_DIRS = FileNameSet("scripts", "i18n", "pynche", "demo", "parser") TOOLS_FILES = FileSuffixSet(".py", ".pyw", ".txt") + def copy_if_modified(src, dest): try: dest_stat = os.stat(dest) @@ -73,12 +75,15 @@ def copy_if_modified(src, dest): do_copy = True else: src_stat = os.stat(src) - do_copy = (src_stat.st_mtime != dest_stat.st_mtime or - src_stat.st_size != dest_stat.st_size) + do_copy = ( + src_stat.st_mtime != dest_stat.st_mtime + or src_stat.st_size != dest_stat.st_size + ) if do_copy: shutil.copy2(src, dest) + def get_lib_layout(ns): def _c(f): if f in EXCLUDE_FROM_LIB: @@ -119,7 +124,7 @@ def get_tcltk_lib(ns): except FileNotFoundError: pass if not tcl_lib or not os.path.isdir(tcl_lib): - warn("Failed to find TCL_LIBRARY") + log_warning("Failed to find TCL_LIBRARY") return for dest, src in rglob(Path(tcl_lib).parent, "**/*"): @@ -148,6 +153,9 @@ def in_build(f, dest="", new_name=None): yield "libs/" + n + ".lib", lib if ns.include_appxmanifest: + yield from in_build("python_uwp.exe", new_name="python{}".format(VER_DOT)) + yield from in_build("pythonw_uwp.exe", new_name="pythonw{}".format(VER_DOT)) + # For backwards compatibility, but we don't reference these ourselves. yield from in_build("python_uwp.exe", new_name="python") yield from in_build("pythonw_uwp.exe", new_name="pythonw") else: @@ -158,9 +166,9 @@ def in_build(f, dest="", new_name=None): if ns.include_launchers and ns.include_appxmanifest: if ns.include_pip: - yield from in_build("python_uwp.exe", new_name="pip") + yield from in_build("python_uwp.exe", new_name="pip{}".format(VER_DOT)) if ns.include_idle: - yield from in_build("pythonw_uwp.exe", new_name="idle") + yield from in_build("pythonw_uwp.exe", new_name="idle{}".format(VER_DOT)) if ns.include_stable: yield from in_build(PYTHON_STABLE_DLL_NAME) @@ -168,7 +176,7 @@ def in_build(f, dest="", new_name=None): for dest, src in rglob(ns.build, "vcruntime*.dll"): yield dest, src - yield "LICENSE.txt", ns.source / "LICENSE" + yield "LICENSE.txt", ns.build / "LICENSE.txt" for dest, src in rglob(ns.build, ("*.pyd", "*.dll")): if src.stem.endswith("_d") != bool(ns.debug) and src not in REQUIRED_DLLS: @@ -222,15 +230,12 @@ def _c(d): yield dest, src if ns.include_pip: - pip_dir = get_pip_dir(ns) - if not pip_dir.is_dir(): - log_warning("Failed to find {} - pip will not be included", pip_dir) - else: - pkg_root = "packages/{}" if ns.zip_lib else "Lib/site-packages/{}" - for dest, src in rglob(pip_dir, "**/*"): - if src in EXCLUDE_FROM_LIB or src in EXCLUDE_FROM_PACKAGED_LIB: - continue - yield pkg_root.format(dest), src + for dest, src in get_pip_layout(ns): + if not isinstance(src, tuple) and ( + src in EXCLUDE_FROM_LIB or src in EXCLUDE_FROM_PACKAGED_LIB + ): + continue + yield dest, src if ns.include_chm: for dest, src in rglob(ns.doc_build / "htmlhelp", PYTHON_CHM_NAME): @@ -244,6 +249,10 @@ def _c(d): for dest, src in get_props_layout(ns): yield dest, src + if ns.include_nuspec: + for dest, src in get_nuspec_layout(ns): + yield dest, src + for dest, src in get_appx_layout(ns): yield dest, src @@ -281,17 +290,18 @@ def _compile_one_py(src, dest, name, optimize, checked=True): log_warning("Failed to compile {}", src) return None - -def _py_temp_compile(src, ns, dest_dir=None, checked=True): +# name argument added to address bpo-37641 +def _py_temp_compile(src, name, ns, dest_dir=None, checked=True): if not ns.precompile or src not in PY_FILES or src.parent in DATA_DIRS: return None - - dest = (dest_dir or ns.temp) / (src.stem + ".py") - return _compile_one_py(src, dest.with_suffix(".pyc"), dest, optimize=2, checked=checked) + dest = (dest_dir or ns.temp) / (src.stem + ".pyc") + return _compile_one_py( + src, dest, name, optimize=2, checked=checked + ) def _write_to_zip(zf, dest, src, ns, checked=True): - pyc = _py_temp_compile(src, ns, checked=checked) + pyc = _py_temp_compile(src, dest, ns, checked=checked) if pyc: try: zf.write(str(pyc), dest.with_suffix(".pyc")) @@ -361,28 +371,9 @@ def generate_source_files(ns): print("# Uncomment to run site.main() automatically", file=f) print("#import site", file=f) - if ns.include_appxmanifest: - log_info("Generating AppxManifest.xml in {}", ns.temp) - ns.temp.mkdir(parents=True, exist_ok=True) - - with open(ns.temp / "AppxManifest.xml", "wb") as f: - f.write(get_appxmanifest(ns)) - - with open(ns.temp / "_resources.xml", "wb") as f: - f.write(get_resources_xml(ns)) - if ns.include_pip: - pip_dir = get_pip_dir(ns) - if not (pip_dir / "pip").is_dir(): - log_info("Extracting pip to {}", pip_dir) - pip_dir.mkdir(parents=True, exist_ok=True) - extract_pip_files(ns) - - if ns.include_props: - log_info("Generating {} in {}", PYTHON_PROPS_NAME, ns.temp) - ns.temp.mkdir(parents=True, exist_ok=True) - with open(ns.temp / PYTHON_PROPS_NAME, "wb") as f: - f.write(get_props(ns)) + log_info("Extracting pip") + extract_pip_files(ns) def _create_zip_file(ns): @@ -427,6 +418,18 @@ def copy_files(files, ns): log_info("Processed {} files", count) log_debug("Processing {!s}", src) + if isinstance(src, tuple): + src, content = src + if ns.copy: + log_debug("Copy {} -> {}", src, ns.copy / dest) + (ns.copy / dest).parent.mkdir(parents=True, exist_ok=True) + with open(ns.copy / dest, "wb") as f: + f.write(content) + if ns.zip: + log_debug("Zip {} into {}", src, ns.zip) + zip_file.writestr(str(dest), content) + continue + if ( ns.precompile and src in PY_FILES diff --git a/PC/layout/support/appxmanifest.py b/PC/layout/support/appxmanifest.py index 49a35fa1f0468e..de5813a2536aee 100644 --- a/PC/layout/support/appxmanifest.py +++ b/PC/layout/support/appxmanifest.py @@ -17,12 +17,7 @@ from .constants import * -__all__ = [] - - -def public(f): - __all__.append(f.__name__) - return f +__all__ = ["get_appx_layout"] APPX_DATA = dict( @@ -70,6 +65,8 @@ def public(f): BackgroundColor="transparent", ) +PY_PNG = '_resources/py.png' + APPXMANIFEST_NS = { "": "http://schemas.microsoft.com/appx/manifest/foundation/windows10", "m": "http://schemas.microsoft.com/appx/manifest/foundation/windows10", @@ -160,15 +157,13 @@ def public(f): "Version": "{}.{}.{}".format(VER_MAJOR, VER_MINOR, VER_MICRO), "InstallPath": { "": "[{AppVPackageRoot}]", - "ExecutablePath": "[{AppVPackageRoot}]\\python.exe", - "WindowedExecutablePath": "[{AppVPackageRoot}]\\pythonw.exe", + "ExecutablePath": "[{{AppVPackageRoot}}]\\python{}.exe".format(VER_DOT), + "WindowedExecutablePath": "[{{AppVPackageRoot}}]\\pythonw{}.exe".format(VER_DOT), }, "Help": { "Main Python Documentation": { "_condition": lambda ns: ns.include_chm, - "": "[{{AppVPackageRoot}}]\\Doc\\{}".format( - PYTHON_CHM_NAME - ), + "": "[{{AppVPackageRoot}}]\\Doc\\{}".format(PYTHON_CHM_NAME), }, "Local Python Documentation": { "_condition": lambda ns: ns.include_html_doc, @@ -239,31 +234,6 @@ def _fixup_sccd(ns, sccd, new_hash=None): return sccd -@public -def get_appx_layout(ns): - if not ns.include_appxmanifest: - return - - yield "AppxManifest.xml", ns.temp / "AppxManifest.xml" - yield "_resources.xml", ns.temp / "_resources.xml" - icons = ns.source / "PC" / "icons" - yield "_resources/pythonx44.png", icons / "pythonx44.png" - yield "_resources/pythonx44$targetsize-44_altform-unplated.png", icons / "pythonx44.png" - yield "_resources/pythonx50.png", icons / "pythonx50.png" - yield "_resources/pythonx50$targetsize-50_altform-unplated.png", icons / "pythonx50.png" - yield "_resources/pythonx150.png", icons / "pythonx150.png" - yield "_resources/pythonx150$targetsize-150_altform-unplated.png", icons / "pythonx150.png" - yield "_resources/pythonwx44.png", icons / "pythonwx44.png" - yield "_resources/pythonwx44$targetsize-44_altform-unplated.png", icons / "pythonwx44.png" - yield "_resources/pythonwx150.png", icons / "pythonwx150.png" - yield "_resources/pythonwx150$targetsize-150_altform-unplated.png", icons / "pythonwx150.png" - sccd = ns.source / SCCD_FILENAME - if sccd.is_file(): - # This should only be set for side-loading purposes. - sccd = _fixup_sccd(ns, sccd, os.getenv("APPX_DATA_SHA256")) - yield sccd.name, sccd - - def find_or_add(xml, element, attr=None, always_add=False): if always_add: e = None @@ -310,12 +280,16 @@ def add_alias(xml, appid, alias, subsystem="windows"): e = find_or_add(e, "uap5:ExecutionAlias", ("Alias", alias)) -def add_file_type(xml, appid, name, suffix, parameters='"%1"'): +def add_file_type(xml, appid, name, suffix, parameters='"%1"', info=None, logo=None): app = _get_app(xml, appid) e = find_or_add(app, "m:Extensions") e = find_or_add(e, "uap3:Extension", ("Category", "windows.fileTypeAssociation")) e = find_or_add(e, "uap3:FileTypeAssociation", ("Name", name)) e.set("Parameters", parameters) + if info: + find_or_add(e, "uap:DisplayName").text = info + if logo: + find_or_add(e, "uap:Logo").text = logo e = find_or_add(e, "uap:SupportedFileTypes") if isinstance(suffix, str): suffix = [suffix] @@ -393,7 +367,6 @@ def disable_registry_virtualization(xml): e = find_or_add(e, "rescap:Capability", ("Name", "unvirtualizedResources")) -@public def get_appxmanifest(ns): for k, v in APPXMANIFEST_NS.items(): ET.register_namespace(k, v) @@ -428,22 +401,22 @@ def get_appxmanifest(ns): ns, xml, "Python", - "python", + "python{}".format(VER_DOT), ["python", "python{}".format(VER_MAJOR), "python{}".format(VER_DOT)], PYTHON_VE_DATA, "console", - ("python.file", [".py"]), + ("python.file", [".py"], '"%1"', 'Python File', PY_PNG), ) add_application( ns, xml, "PythonW", - "pythonw", + "pythonw{}".format(VER_DOT), ["pythonw", "pythonw{}".format(VER_MAJOR), "pythonw{}".format(VER_DOT)], PYTHONW_VE_DATA, "windows", - ("python.windowedfile", [".pyw"]), + ("python.windowedfile", [".pyw"], '"%1"', 'Python File (no console)', PY_PNG), ) if ns.include_pip and ns.include_launchers: @@ -451,11 +424,11 @@ def get_appxmanifest(ns): ns, xml, "Pip", - "pip", + "pip{}".format(VER_DOT), ["pip", "pip{}".format(VER_MAJOR), "pip{}".format(VER_DOT)], PIP_VE_DATA, "console", - ("python.wheel", [".whl"], 'install "%1"'), + ("python.wheel", [".whl"], 'install "%1"', 'Python Wheel'), ) if ns.include_idle and ns.include_launchers: @@ -463,7 +436,7 @@ def get_appxmanifest(ns): ns, xml, "Idle", - "idle", + "idle{}".format(VER_DOT), ["idle", "idle{}".format(VER_MAJOR), "idle{}".format(VER_DOT)], IDLE_VE_DATA, "windows", @@ -481,6 +454,28 @@ def get_appxmanifest(ns): return buffer.getbuffer() -@public def get_resources_xml(ns): return RESOURCES_XML_TEMPLATE.encode("utf-8") + + +def get_appx_layout(ns): + if not ns.include_appxmanifest: + return + + yield "AppxManifest.xml", ("AppxManifest.xml", get_appxmanifest(ns)) + yield "_resources.xml", ("_resources.xml", get_resources_xml(ns)) + icons = ns.source / "PC" / "icons" + for px in [44, 50, 150]: + src = icons / "pythonx{}.png".format(px) + yield f"_resources/pythonx{px}.png", src + yield f"_resources/pythonx{px}$targetsize-{px}_altform-unplated.png", src + for px in [44, 150]: + src = icons / "pythonwx{}.png".format(px) + yield f"_resources/pythonwx{px}.png", src + yield f"_resources/pythonwx{px}$targetsize-{px}_altform-unplated.png", src + yield f"_resources/py.png", icons / "py.png" + sccd = ns.source / SCCD_FILENAME + if sccd.is_file(): + # This should only be set for side-loading purposes. + sccd = _fixup_sccd(ns, sccd, os.getenv("APPX_DATA_SHA256")) + yield sccd.name, sccd diff --git a/PC/layout/support/constants.py b/PC/layout/support/constants.py index 88ea410b340ea5..d76fa3bbf3b476 100644 --- a/PC/layout/support/constants.py +++ b/PC/layout/support/constants.py @@ -10,7 +10,7 @@ VER_MAJOR, VER_MINOR, VER_MICRO, VER_FIELD4 = struct.pack(">i", sys.hexversion) VER_FIELD3 = VER_MICRO << 8 | VER_FIELD4 -VER_NAME = {"alpha": "a", "beta": "b", "rc": "rc"}.get( +VER_NAME = {"alpha": "a", "beta": "b", "candidate": "rc"}.get( sys.version_info.releaselevel, "" ) VER_SERIAL = sys.version_info.serial if VER_NAME else "" diff --git a/PC/layout/support/nuspec.py b/PC/layout/support/nuspec.py new file mode 100644 index 00000000000000..ba26ff337e91e6 --- /dev/null +++ b/PC/layout/support/nuspec.py @@ -0,0 +1,66 @@ +""" +Provides .props file. +""" + +import os + +from .constants import * + +__all__ = ["get_nuspec_layout"] + +PYTHON_NUSPEC_NAME = "python.nuspec" + +NUSPEC_DATA = { + "PYTHON_TAG": VER_DOT, + "PYTHON_VERSION": os.getenv("PYTHON_NUSPEC_VERSION"), + "PYTHON_BITNESS": "64-bit" if IS_X64 else "32-bit", + "PACKAGENAME": os.getenv("PYTHON_NUSPEC_PACKAGENAME"), + "PACKAGETITLE": os.getenv("PYTHON_NUSPEC_PACKAGETITLE"), + "FILELIST": r' ', +} + +if not NUSPEC_DATA["PYTHON_VERSION"]: + if VER_NAME: + NUSPEC_DATA["PYTHON_VERSION"] = "{}.{}-{}{}".format( + VER_DOT, VER_MICRO, VER_NAME, VER_SERIAL + ) + else: + NUSPEC_DATA["PYTHON_VERSION"] = "{}.{}".format(VER_DOT, VER_MICRO) + +if not NUSPEC_DATA["PACKAGETITLE"]: + NUSPEC_DATA["PACKAGETITLE"] = "Python" if IS_X64 else "Python (32-bit)" + +if not NUSPEC_DATA["PACKAGENAME"]: + NUSPEC_DATA["PACKAGENAME"] = "python" if IS_X64 else "pythonx86" + +FILELIST_WITH_PROPS = r""" + """ + +NUSPEC_TEMPLATE = r""" + + + {PACKAGENAME} + {PACKAGETITLE} + {PYTHON_VERSION} + Python Software Foundation + tools\LICENSE.txt + https://www.python.org/ + Installs {PYTHON_BITNESS} Python for use in build scenarios. + https://www.python.org/static/favicon.ico + python + + +{FILELIST} + + +""" + + +def get_nuspec_layout(ns): + if ns.include_all or ns.include_nuspec: + data = NUSPEC_DATA + if ns.include_all or ns.include_props: + data = dict(data) + data["FILELIST"] = FILELIST_WITH_PROPS + nuspec = NUSPEC_TEMPLATE.format_map(data) + yield "python.nuspec", ("python.nuspec", nuspec.encode("utf-8")) diff --git a/PC/layout/support/options.py b/PC/layout/support/options.py index 00f05667ebb7af..5e1543b59ccd59 100644 --- a/PC/layout/support/options.py +++ b/PC/layout/support/options.py @@ -17,6 +17,7 @@ def public(f): 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"}, @@ -30,6 +31,7 @@ def public(f): "launchers": {"help": "specific launchers"}, "appxmanifest": {"help": "an appxmanifest"}, "props": {"help": "a python.props file"}, + "nuspec": {"help": "a python.nuspec file"}, "chm": {"help": "the CHM documentation"}, "html-doc": {"help": "the HTML documentation"}, } @@ -41,6 +43,7 @@ def public(f): "options": [ "stable", "pip", + "pip-user", "distutils", "tcltk", "idle", @@ -60,13 +63,11 @@ def public(f): "stable", "distutils", "venv", - "props" + "props", + "nuspec", ], }, - "iot": { - "help": "Windows IoT Core", - "options": ["stable", "pip"], - }, + "iot": {"help": "Windows IoT Core", "options": ["stable", "pip"]}, "default": { "help": "development kit package", "options": [ diff --git a/PC/layout/support/pip.py b/PC/layout/support/pip.py index 369a923ce139fb..c54acb250a252e 100644 --- a/PC/layout/support/pip.py +++ b/PC/layout/support/pip.py @@ -11,15 +11,11 @@ import subprocess import sys -__all__ = [] +from .filesets import * +__all__ = ["extract_pip_files", "get_pip_layout"] -def public(f): - __all__.append(f.__name__) - return f - -@public def get_pip_dir(ns): if ns.copy: if ns.zip_lib: @@ -29,10 +25,28 @@ def get_pip_dir(ns): return ns.temp / "packages" -@public +def get_pip_layout(ns): + pip_dir = get_pip_dir(ns) + if not pip_dir.is_dir(): + log_warning("Failed to find {} - pip will not be included", pip_dir) + else: + pkg_root = "packages/{}" if ns.zip_lib else "Lib/site-packages/{}" + for dest, src in rglob(pip_dir, "**/*"): + yield pkg_root.format(dest), src + if ns.include_pip_user: + content = "\n".join( + "[{}]\nuser=yes".format(n) + for n in ["install", "uninstall", "freeze", "list"] + ) + yield "pip.ini", ("pip.ini", content.encode()) + + def extract_pip_files(ns): dest = get_pip_dir(ns) - dest.mkdir(parents=True, exist_ok=True) + try: + dest.mkdir(parents=True, exist_ok=False) + except IOError: + return src = ns.source / "Lib" / "ensurepip" / "_bundled" @@ -58,6 +72,7 @@ def extract_pip_files(ns): "--target", str(dest), "--no-index", + "--no-compile", "--no-cache-dir", "-f", str(src), diff --git a/PC/layout/support/props.py b/PC/layout/support/props.py index 3a047d21505834..4d3b06195f6ed2 100644 --- a/PC/layout/support/props.py +++ b/PC/layout/support/props.py @@ -6,13 +6,7 @@ from .constants import * -__all__ = ["PYTHON_PROPS_NAME"] - - -def public(f): - __all__.append(f.__name__) - return f - +__all__ = ["get_props_layout"] PYTHON_PROPS_NAME = "python.props" @@ -97,14 +91,8 @@ def public(f): """ -@public def get_props_layout(ns): if ns.include_all or ns.include_props: - yield "python.props", ns.temp / "python.props" - - -@public -def get_props(ns): - # TODO: Filter contents of props file according to included/excluded items - props = PROPS_TEMPLATE.format_map(PROPS_DATA) - return props.encode("utf-8") + # TODO: Filter contents of props file according to included/excluded items + props = PROPS_TEMPLATE.format_map(PROPS_DATA) + yield "python.props", ("python.props", props.encode("utf-8")) diff --git a/PC/pyconfig.h b/PC/pyconfig.h index a74ee98a753d88..b40e24f438ef60 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -122,13 +122,13 @@ WIN32 is still required for the locale module. #if defined(_M_X64) || defined(_M_AMD64) #if defined(__INTEL_COMPILER) #define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 64 bit (amd64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") -#elif defined(_M_ARM64) -#define COMPILER _Py_PASTE_VERSION("64 bit (ARM)") -#define PYD_PLATFORM_TAG "win_arm64" #else #define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") #endif /* __INTEL_COMPILER */ #define PYD_PLATFORM_TAG "win_amd64" +#elif defined(_M_ARM64) +#define COMPILER _Py_PASTE_VERSION("64 bit (ARM64)") +#define PYD_PLATFORM_TAG "win_arm64" #else #define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") #endif @@ -295,7 +295,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ # define SIZEOF_FPOS_T 8 # define SIZEOF_HKEY 8 # define SIZEOF_SIZE_T 8 -/* configure.ac defines HAVE_LARGEFILE_SUPPORT iff HAVE_LONG_LONG, +/* configure.ac defines HAVE_LARGEFILE_SUPPORT iff sizeof(off_t) > sizeof(long), and sizeof(PY_LONG_LONG) >= sizeof(off_t). On Win64 the second condition is not true, but if fpos_t replaces off_t then this is true. The uses of HAVE_LARGEFILE_SUPPORT imply that Win64 diff --git a/PC/python3.def b/PC/python3.def index e317864d0cd802..5d93c18af87ec2 100644 --- a/PC/python3.def +++ b/PC/python3.def @@ -235,7 +235,6 @@ EXPORTS PyExc_SystemError=python38.PyExc_SystemError DATA PyExc_SystemExit=python38.PyExc_SystemExit DATA PyExc_TabError=python38.PyExc_TabError DATA - PyExc_TargetScopeError=python38.PyExc_TargetScopeError DATA PyExc_TimeoutError=python38.PyExc_TimeoutError DATA PyExc_TypeError=python38.PyExc_TypeError DATA PyExc_UnboundLocalError=python38.PyExc_UnboundLocalError DATA diff --git a/PC/python_uwp.cpp b/PC/python_uwp.cpp index 5c8caa6666c4e0..88369e8fbfeb38 100644 --- a/PC/python_uwp.cpp +++ b/PC/python_uwp.cpp @@ -6,6 +6,9 @@ #define WIN32_LEAN_AND_MEAN #include #include +#include + +#include #include #include @@ -24,192 +27,225 @@ const wchar_t *PROGNAME = L"python.exe"; #endif #endif -static void -set_user_base() +static std::wstring +get_user_base() { - wchar_t envBuffer[2048]; try { const auto appData = winrt::Windows::Storage::ApplicationData::Current(); if (appData) { const auto localCache = appData.LocalCacheFolder(); if (localCache) { auto path = localCache.Path(); - if (!path.empty() && - !wcscpy_s(envBuffer, path.c_str()) && - !wcscat_s(envBuffer, L"\\local-packages") - ) { - _wputenv_s(L"PYTHONUSERBASE", envBuffer); + if (!path.empty()) { + return std::wstring(path) + L"\\local-packages"; } } } } catch (...) { } + return std::wstring(); } -static const wchar_t * -get_argv0(const wchar_t *argv0) +static std::wstring +get_package_family() { - winrt::hstring installPath; - const wchar_t *launcherPath; - wchar_t *buffer; - size_t len; - - launcherPath = _wgetenv(L"__PYVENV_LAUNCHER__"); - if (launcherPath && launcherPath[0]) { - len = wcslen(launcherPath) + 1; - buffer = (wchar_t *)malloc(sizeof(wchar_t) * len); - if (!buffer) { - Py_FatalError("out of memory"); - return NULL; - } - if (wcscpy_s(buffer, len, launcherPath)) { - Py_FatalError("failed to copy to buffer"); - return NULL; + try { + const auto package = winrt::Windows::ApplicationModel::Package::Current(); + if (package) { + const auto id = package.Id(); + if (id) { + return std::wstring(id.FamilyName()); + } } - return buffer; } + catch (...) { + } + + return std::wstring(); +} +static std::wstring +get_package_home() +{ try { const auto package = winrt::Windows::ApplicationModel::Package::Current(); if (package) { - const auto install = package.InstalledLocation(); - if (install) { - installPath = install.Path(); + const auto path = package.InstalledLocation(); + if (path) { + return std::wstring(path.Path()); } } } catch (...) { } - if (!installPath.empty()) { - len = installPath.size() + wcslen(PROGNAME) + 2; - } else { - len = wcslen(argv0) + wcslen(PROGNAME) + 1; - } + return std::wstring(); +} - buffer = (wchar_t *)malloc(sizeof(wchar_t) * len); - if (!buffer) { - Py_FatalError("out of memory"); - return NULL; - } +static PyStatus +set_process_name(PyConfig *config) +{ + PyStatus status = PyStatus_Ok(); + std::wstring executable; - if (!installPath.empty()) { - if (wcscpy_s(buffer, len, installPath.c_str())) { - Py_FatalError("failed to copy to buffer"); - return NULL; - } - if (wcscat_s(buffer, len, L"\\")) { - Py_FatalError("failed to concatenate backslash"); - return NULL; - } - } else { - if (wcscpy_s(buffer, len, argv0)) { - Py_FatalError("failed to copy argv[0]"); - return NULL; + const auto home = get_package_home(); + const auto family = get_package_family(); + + if (!family.empty()) { + PWSTR localAppData; + if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, + NULL, &localAppData))) { + executable = std::wstring(localAppData) + + L"\\Microsoft\\WindowsApps\\" + + family + + L"\\" + + PROGNAME; + + CoTaskMemFree(localAppData); } + } - wchar_t *name = wcsrchr(buffer, L'\\'); - if (name) { - name[1] = L'\0'; + /* Only use module filename if we don't have a home */ + if (home.empty() && executable.empty()) { + executable.resize(MAX_PATH); + while (true) { + DWORD len = GetModuleFileNameW( + NULL, executable.data(), (DWORD)executable.size()); + if (len == 0) { + executable.clear(); + break; + } else if (len == executable.size() && + GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + executable.resize(len * 2); + } else { + executable.resize(len); + break; + } + } + size_t i = executable.find_last_of(L"/\\"); + if (i == std::wstring::npos) { + executable = PROGNAME; } else { - buffer[0] = L'\0'; + executable.replace(i + 1, std::wstring::npos, PROGNAME); } } - if (wcscat_s(buffer, len, PROGNAME)) { - Py_FatalError("failed to concatenate program name"); - return NULL; + if (!home.empty()) { + status = PyConfig_SetString(config, &config->home, home.c_str()); + if (PyStatus_Exception(status)) { + return status; + } } - return buffer; -} - -static wchar_t * -get_process_name() -{ - DWORD bufferLen = MAX_PATH; - DWORD len = bufferLen; - wchar_t *r = NULL; - - while (!r) { - r = (wchar_t *)malloc(bufferLen * sizeof(wchar_t)); - if (!r) { - Py_FatalError("out of memory"); - return NULL; - } - len = GetModuleFileNameW(NULL, r, bufferLen); - if (len == 0) { - free((void *)r); - return NULL; - } else if (len == bufferLen && - GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - free(r); - r = NULL; - bufferLen *= 2; + const wchar_t *launcherPath = _wgetenv(L"__PYVENV_LAUNCHER__"); + if (launcherPath) { + if (!executable.empty()) { + status = PyConfig_SetString(config, &config->base_executable, + executable.c_str()); + if (PyStatus_Exception(status)) { + return status; + } } + + status = PyConfig_SetString( + config, &config->executable, launcherPath); + + /* bpo-35873: Clear the environment variable to avoid it being + * inherited by child processes. */ + _wputenv_s(L"__PYVENV_LAUNCHER__", L""); + } else if (!executable.empty()) { + status = PyConfig_SetString( + config, &config->executable, executable.c_str()); } - return r; + return status; } int wmain(int argc, wchar_t **argv) { - const wchar_t **new_argv; - int new_argc; - const wchar_t *exeName; + PyStatus status; + PyPreConfig preconfig; + PyConfig config; - new_argc = argc; - new_argv = (const wchar_t**)malloc(sizeof(wchar_t *) * (argc + 2)); - if (new_argv == NULL) { - Py_FatalError("out of memory"); - return -1; + const wchar_t *moduleName = NULL; + const wchar_t *p = wcsrchr(argv[0], L'\\'); + if (!p) { + p = argv[0]; } + if (p) { + if (*p == L'\\') { + p++; + } - exeName = get_process_name(); + if (wcsnicmp(p, L"pip", 3) == 0) { + moduleName = L"pip"; + } else if (wcsnicmp(p, L"idle", 4) == 0) { + moduleName = L"idlelib"; + } + } - new_argv[0] = get_argv0(exeName ? exeName : argv[0]); - for (int i = 1; i < argc; ++i) { - new_argv[i] = argv[i]; + PyPreConfig_InitPythonConfig(&preconfig); + if (!moduleName) { + status = Py_PreInitializeFromArgs(&preconfig, argc, argv); + if (PyStatus_Exception(status)) { + goto fail_without_config; + } } - set_user_base(); + PyConfig_InitPythonConfig(&config); - if (exeName) { - const wchar_t *p = wcsrchr(exeName, L'\\'); - if (p) { - const wchar_t *moduleName = NULL; - if (*p++ == L'\\') { - if (wcsnicmp(p, L"pip", 3) == 0) { - moduleName = L"pip"; - _wputenv_s(L"PIP_USER", L"true"); - } - else if (wcsnicmp(p, L"idle", 4) == 0) { - moduleName = L"idlelib"; - } - } + status = PyConfig_SetArgv(&config, argc, argv); + if (PyStatus_Exception(status)) { + goto fail; + } + if (moduleName) { + config.parse_argv = 0; + } - if (moduleName) { - new_argc += 2; - for (int i = argc; i >= 1; --i) { - new_argv[i + 2] = new_argv[i]; - } - new_argv[1] = L"-m"; - new_argv[2] = moduleName; - } - } + status = set_process_name(&config); + if (PyStatus_Exception(status)) { + goto fail; + } + + p = _wgetenv(L"PYTHONUSERBASE"); + if (!p || !*p) { + _wputenv_s(L"PYTHONUSERBASE", get_user_base().c_str()); } - /* Override program_full_path from here so that - sys.executable is set correctly. */ - _Py_SetProgramFullPath(new_argv[0]); + if (moduleName) { + status = PyConfig_SetString(&config, &config.run_module, moduleName); + if (PyStatus_Exception(status)) { + goto fail; + } + status = PyConfig_SetString(&config, &config.run_filename, NULL); + if (PyStatus_Exception(status)) { + goto fail; + } + status = PyConfig_SetString(&config, &config.run_command, NULL); + if (PyStatus_Exception(status)) { + goto fail; + } + } - int result = Py_Main(new_argc, (wchar_t **)new_argv); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + goto fail; + } + PyConfig_Clear(&config); - free((void *)exeName); - free((void *)new_argv); + return Py_RunMain(); - return result; +fail: + PyConfig_Clear(&config); +fail_without_config: + if (PyStatus_IsExit(status)) { + return status.exitcode; + } + assert(PyStatus_Exception(status)); + Py_ExitStatusException(status); + /* Unreachable code */ + return 0; } #ifdef PYTHONW diff --git a/PC/winreg.c b/PC/winreg.c index 5f5fc85d225075..72a7c380beefe1 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -518,11 +518,18 @@ fixupMultiSZ(wchar_t **str, wchar_t *data, int len) int i; wchar_t *Q; - Q = data + len; - for (P = data, i = 0; P < Q && *P != '\0'; P++, i++) { + if (len > 0 && data[len - 1] == '\0') { + Q = data + len - 1; + } + else { + Q = data + len; + } + + for (P = data, i = 0; P < Q; P++, i++) { str[i] = P; - for (; P < Q && *P != '\0'; P++) + for (; P < Q && *P != '\0'; P++) { ; + } } } @@ -530,12 +537,20 @@ static int countStrings(wchar_t *data, int len) { int strings; - wchar_t *P; - wchar_t *Q = data + len; + wchar_t *P, *Q; + + if (len > 0 && data[len - 1] == '\0') { + Q = data + len - 1; + } + else { + Q = data + len; + } - for (P = data, strings = 0; P < Q && *P != '\0'; P++, strings++) - for (; P < Q && *P != '\0'; P++) + for (P = data, strings = 0; P < Q; P++, strings++) { + for (; P < Q && *P != '\0'; P++) { ; + } + } return strings; } @@ -749,21 +764,15 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) } for (index = 0; index < s; index++) { - size_t len = wcslen(str[index]); - if (len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "registry string is too long for a Python string"); - Py_DECREF(obData); - PyMem_Free(str); - return NULL; - } - PyObject *uni = PyUnicode_FromWideChar(str[index], len); + size_t slen = wcsnlen(str[index], len); + PyObject *uni = PyUnicode_FromWideChar(str[index], slen); if (uni == NULL) { Py_DECREF(obData); PyMem_Free(str); return NULL; } PyList_SET_ITEM(obData, index, uni); + len -= Py_SAFE_DOWNCAST(slen + 1, size_t, int); } PyMem_Free(str); @@ -1702,7 +1711,7 @@ winreg.DisableReflectionKey Disables registry reflection for 32bit processes running on a 64bit OS. -Will generally raise NotImplemented if executed on a 32bit OS. +Will generally raise NotImplementedError if executed on a 32bit OS. If the key is not on the reflection list, the function succeeds but has no effect. Disabling reflection for a key does not affect reflection @@ -1711,7 +1720,7 @@ of any subkeys. static PyObject * winreg_DisableReflectionKey_impl(PyObject *module, HKEY key) -/*[clinic end generated code: output=830cce504cc764b4 input=a6c9e5ca5410193c]*/ +/*[clinic end generated code: output=830cce504cc764b4 input=70bece2dee02e073]*/ { HMODULE hMod; typedef LONG (WINAPI *RDRKFunc)(HKEY); @@ -1749,14 +1758,14 @@ winreg.EnableReflectionKey Restores registry reflection for the specified disabled key. -Will generally raise NotImplemented if executed on a 32bit OS. +Will generally raise NotImplementedError if executed on a 32bit OS. Restoring reflection for a key does not affect reflection of any subkeys. [clinic start generated code]*/ static PyObject * winreg_EnableReflectionKey_impl(PyObject *module, HKEY key) -/*[clinic end generated code: output=86fa1385fdd9ce57 input=7748abbacd1e166a]*/ +/*[clinic end generated code: output=86fa1385fdd9ce57 input=eeae770c6eb9f559]*/ { HMODULE hMod; typedef LONG (WINAPI *RERKFunc)(HKEY); @@ -1794,12 +1803,12 @@ winreg.QueryReflectionKey Returns the reflection state for the specified key as a bool. -Will generally raise NotImplemented if executed on a 32bit OS. +Will generally raise NotImplementedError if executed on a 32bit OS. [clinic start generated code]*/ static PyObject * winreg_QueryReflectionKey_impl(PyObject *module, HKEY key) -/*[clinic end generated code: output=4e774af288c3ebb9 input=9f325eacb5a65d88]*/ +/*[clinic end generated code: output=4e774af288c3ebb9 input=a98fa51d55ade186]*/ { HMODULE hMod; typedef LONG (WINAPI *RQRKFunc)(HKEY, BOOL *); diff --git a/PCbuild/_elementtree.vcxproj b/PCbuild/_elementtree.vcxproj index 33a017327189ed..4a125b243b780d 100644 --- a/PCbuild/_elementtree.vcxproj +++ b/PCbuild/_elementtree.vcxproj @@ -116,7 +116,6 @@ - diff --git a/PCbuild/_elementtree.vcxproj.filters b/PCbuild/_elementtree.vcxproj.filters index 4597ee521b3331..6acdf35846ab14 100644 --- a/PCbuild/_elementtree.vcxproj.filters +++ b/PCbuild/_elementtree.vcxproj.filters @@ -33,9 +33,6 @@ Header Files - - Header Files - Header Files diff --git a/PCbuild/_msi.vcxproj b/PCbuild/_msi.vcxproj index 9f089ac7f52f55..720eb2931be72d 100644 --- a/PCbuild/_msi.vcxproj +++ b/PCbuild/_msi.vcxproj @@ -70,6 +70,7 @@ {31FFC478-7B4A-43E8-9954-8D03E2187E9C} _msi Win32Proj + false diff --git a/PCbuild/_tkinter.vcxproj b/PCbuild/_tkinter.vcxproj index fdfa59648aa904..af813b77c1d1c8 100644 --- a/PCbuild/_tkinter.vcxproj +++ b/PCbuild/_tkinter.vcxproj @@ -122,7 +122,7 @@ - + diff --git a/PCbuild/build.bat b/PCbuild/build.bat index 6f0c85e4a45a03..bce599329e73ab 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -76,7 +76,7 @@ if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts if "%~1"=="--pgo" (set do_pgo=true) & shift & goto CheckOpts if "%~1"=="--pgo-job" (set do_pgo=true) & (set pgo_job=%~2) & shift & shift & goto CheckOpts if "%~1"=="--test-marker" (set UseTestMarker=true) & shift & goto CheckOpts -if "%~1"=="-V" shift & goto Version +if "%~1"=="-V" shift & goto :Version rem These use the actual property names used by MSBuild. We could just let rem them in through the environment, but we specify them on the command line rem anyway for visibility so set defaults after this @@ -111,10 +111,16 @@ call "%dir%find_msbuild.bat" %MSBUILD% if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) if "%kill%"=="true" call :Kill +if ERRORLEVEL 1 exit /B 3 if "%do_pgo%"=="true" ( set conf=PGInstrument call :Build %1 %2 %3 %4 %5 %6 %7 %8 %9 +) +rem %VARS% are evaluated eagerly, which would lose the ERRORLEVEL +rem value if we didn't split it out here. +if "%do_pgo%"=="true" if ERRORLEVEL 1 exit /B %ERRORLEVEL% +if "%do_pgo%"=="true" ( del /s "%dir%\*.pgc" del /s "%dir%\..\Lib\*.pyc" echo on @@ -124,7 +130,8 @@ if "%do_pgo%"=="true" ( set conf=PGUpdate set target=Build ) -goto Build +goto :Build + :Kill echo on %MSBUILD% "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^ @@ -132,7 +139,7 @@ echo on /p:KillPython=true @echo off -goto :eof +exit /B %ERRORLEVEL% :Build rem Call on MSBuild to do the work, echo the command. @@ -148,9 +155,11 @@ echo on %1 %2 %3 %4 %5 %6 %7 %8 %9 @echo off -goto :eof +exit /b %ERRORLEVEL% :Version rem Display the current build version information call "%dir%find_msbuild.bat" %MSBUILD% -if not ERRORLEVEL 1 %MSBUILD% "%dir%pythoncore.vcxproj" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9 +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) +%MSBUILD% "%dir%pythoncore.vcxproj" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9 +if ERRORLEVEL 1 exit /b 3 \ No newline at end of file diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 42ffe6f485fac1..100149e83c1645 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -53,8 +53,8 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.6 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0-rc0-r1 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1b -set libraries=%libraries% sqlite-3.21.0.0 +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1d +set libraries=%libraries% sqlite-3.28.0.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.9.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.9.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6 @@ -77,7 +77,7 @@ echo.Fetching external binaries... set binaries= if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1b +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1d if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.9.0 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 diff --git a/PCbuild/pyexpat.vcxproj b/PCbuild/pyexpat.vcxproj index 28a11a82936ee2..b2d9f5d57d4975 100644 --- a/PCbuild/pyexpat.vcxproj +++ b/PCbuild/pyexpat.vcxproj @@ -100,7 +100,6 @@ - diff --git a/PCbuild/pyexpat.vcxproj.filters b/PCbuild/pyexpat.vcxproj.filters index cb02847980c634..f8d46026c9c284 100644 --- a/PCbuild/pyexpat.vcxproj.filters +++ b/PCbuild/pyexpat.vcxproj.filters @@ -20,9 +20,6 @@ Source Files - - Source Files - Source Files diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index 12f07dd51287e7..7c0f50be9ea8ea 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -1,6 +1,8 @@ - - + + + + <__PyProject_Props_Imported>true <_ProjectFileVersion>10.0.30319.1 10.0 $(BuildPath) @@ -29,7 +31,7 @@ $(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)PC;$(IntDir);%(AdditionalIncludeDirectories) WIN32;$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions) - + MaxSpeed true true @@ -147,15 +149,15 @@ public override bool Execute() { - + - + @@ -189,8 +191,8 @@ public override bool Execute() { $(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot81)\bin\x86 $(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot)\bin\x86 $(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A@InstallationFolder)\Bin\ - <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificate)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /q /a /n "$(SigningCertificate)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)" - <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificateSha1)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /q /a /sha1 "$(SigningCertificateSha1)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)" + <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificate)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /a /n "$(SigningCertificate)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)" + <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificateSha1)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /a /sha1 "$(SigningCertificateSha1)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)" <_MakeCatCommand Condition="Exists($(SdkBinPath))">"$(SdkBinPath)\makecat.exe" diff --git a/PCbuild/python.props b/PCbuild/python.props index 11638fe348c863..8583138feb6be7 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -1,6 +1,7 @@ - + + <__Python_Props_Imported>true Win32 Release + v142 v141 v140 v120 @@ -54,14 +56,14 @@ $(EXTERNALS_DIR) $([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`)) $(ExternalsDir)\ - $(ExternalsDir)sqlite-3.21.0.0\ + $(ExternalsDir)sqlite-3.28.0.0\ $(ExternalsDir)bzip2-1.0.6\ $(ExternalsDir)xz-5.2.2\ $(ExternalsDir)libffi\ $(ExternalsDir)libffi\$(ArchName)\ $(libffiOutDir)include - $(ExternalsDir)openssl-1.1.1b\ - $(ExternalsDir)openssl-bin-1.1.1b\$(ArchName)\ + $(ExternalsDir)openssl-1.1.1d\ + $(ExternalsDir)openssl-bin-1.1.1d\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ $(ExternalsDir)\zlib-1.2.11\ @@ -79,6 +81,9 @@ $(BuildPath)python$(PyDebugExt).exe + + + true @@ -214,6 +219,7 @@ + diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj index bd051461e9cd3e..2094420a8df395 100644 --- a/PCbuild/python.vcxproj +++ b/PCbuild/python.vcxproj @@ -1,4 +1,4 @@ - + @@ -82,6 +82,7 @@ + @@ -144,4 +145,23 @@ $(_PGOPath) + + + + + <_LicenseFiles Include="@(LicenseFiles)"> + $([System.IO.File]::ReadAllText(%(FullPath))) + + + + + diff --git a/PCbuild/python_uwp.vcxproj b/PCbuild/python_uwp.vcxproj index af187dd4df30b0..14e138cbed3e00 100644 --- a/PCbuild/python_uwp.vcxproj +++ b/PCbuild/python_uwp.vcxproj @@ -65,6 +65,15 @@ Console + + + Multithreaded + + + ucrt.lib;%(AdditionalDependencies) + libucrt;%(IgnoreSpecificDefaultLibraries) + + diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 89625da944e1ab..13c3b594e44314 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -331,6 +331,7 @@ + @@ -511,7 +512,7 @@ - + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 63ab88b4a01ddc..ebab1193018366 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -605,6 +605,9 @@ Modules + + Modules + Modules diff --git a/PCbuild/pythonw_uwp.vcxproj b/PCbuild/pythonw_uwp.vcxproj index 79e105877fbeb2..e2c01710498eec 100644 --- a/PCbuild/pythonw_uwp.vcxproj +++ b/PCbuild/pythonw_uwp.vcxproj @@ -65,6 +65,15 @@ Windows + + + Multithreaded + + + ucrt.lib;%(AdditionalDependencies) + libucrt;%(IgnoreSpecificDefaultLibraries) + + diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index cf4aa4c917544d..80e3359df3ddbe 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -165,7 +165,7 @@ _lzma Homepage: http://tukaani.org/xz/ _ssl - Python wrapper for version 1.1.1b of the OpenSSL secure sockets + Python wrapper for version 1.1.1c of the OpenSSL secure sockets library, which is downloaded from our binaries repository at https://github.com/python/cpython-bin-deps. @@ -184,7 +184,7 @@ _ssl again when building. _sqlite3 - Wraps SQLite 3.21.0.0, which is itself built by sqlite3.vcxproj + Wraps SQLite 3.28.0.0, which is itself built by sqlite3.vcxproj Homepage: http://www.sqlite.org/ _tkinter diff --git a/PCbuild/rt.bat b/PCbuild/rt.bat index e603de6d5174f8..59f757c0f5888a 100644 --- a/PCbuild/rt.bat +++ b/PCbuild/rt.bat @@ -39,6 +39,7 @@ if "%1"=="-O" (set dashO=-O) & shift & goto CheckOpts if "%1"=="-q" (set qmode=yes) & shift & goto CheckOpts if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts if "%1"=="-x64" (set prefix=%pcbuild%amd64) & shift & goto CheckOpts +if "%1"=="-arm64" (set prefix=%pcbuild%arm64) & shift & goto CheckOpts if "%1"=="-arm32" (set prefix=%pcbuild%arm32) & shift & goto CheckOpts if NOT "%1"=="" (set regrtestargs=%regrtestargs% %1) & shift & goto CheckOpts diff --git a/PCbuild/tcltk.props b/PCbuild/tcltk.props index b185cb7b1e2818..7fcd3e1c618c46 100644 --- a/PCbuild/tcltk.props +++ b/PCbuild/tcltk.props @@ -1,6 +1,6 @@ - - - + + + 8 6 @@ -42,4 +42,19 @@ $(BuildDirTop)_VC11 $(BuildDirTop)_VC10 + + + + + <_TclTkLib Include="$(tcltkdir)\lib\**\*" /> + + + diff --git a/PCbuild/winsound.vcxproj b/PCbuild/winsound.vcxproj index 56da96a85528a6..32cedc9b444902 100644 --- a/PCbuild/winsound.vcxproj +++ b/PCbuild/winsound.vcxproj @@ -70,6 +70,7 @@ {28B5D777-DDF2-4B6B-B34F-31D938813856} winsound Win32Proj + false diff --git a/Parser/Python.asdl b/Parser/Python.asdl index 0c00d398b4610e..126d478975bbbb 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -111,7 +111,7 @@ module Python excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body) attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset) - arguments = (arg* args, arg* posonlyargs, arg? vararg, arg* kwonlyargs, + arguments = (arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults, arg? kwarg, expr* defaults) arg = (identifier arg, expr? annotation, string? type_comment) diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 582c6ca57b65c4..574fcb0e2faaf5 100644 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -1191,12 +1191,6 @@ class PartingShots(StaticVisitor): /* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) { - return PyAST_obj2mod_ex(ast, arena, mode, PY_MINOR_VERSION); -} - -mod_ty PyAST_obj2mod_ex(PyObject* ast, PyArena* arena, int mode, int feature_version) -{ - mod_ty res; PyObject *req_type[3]; char *req_name[] = {"Module", "Expression", "Interactive"}; int isinstance; @@ -1222,6 +1216,8 @@ class PartingShots(StaticVisitor): req_name[mode], Py_TYPE(ast)->tp_name); return NULL; } + + mod_ty res = NULL; if (obj2ast_mod(ast, &res, arena) != 0) return NULL; else @@ -1280,7 +1276,6 @@ def main(srcfile, dump_module=False): f.write("\n") f.write("PyObject* PyAST_mod2obj(mod_ty t);\n") f.write("mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode);\n") - f.write("mod_ty PyAST_obj2mod_ex(PyObject* ast, PyArena* arena, int mode, int feature_version);\n") f.write("int PyAST_Check(PyObject* obj);\n") f.write('\n') f.write('#ifdef __cplusplus\n') diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index c2ec659fed888f..5763e47c4b00b3 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -956,6 +956,7 @@ tok_nextc(struct tok_state *tok) while (!done) { Py_ssize_t curstart = tok->start == NULL ? -1 : tok->start - tok->buf; + Py_ssize_t cur_multi_line_start = tok->multi_line_start - tok->buf; Py_ssize_t curvalid = tok->inp - tok->buf; Py_ssize_t newsize = curvalid + BUFSIZ; char *newbuf = tok->buf; @@ -968,6 +969,7 @@ tok_nextc(struct tok_state *tok) } tok->buf = newbuf; tok->cur = tok->buf + cur; + tok->multi_line_start = tok->buf + cur_multi_line_start; tok->line_start = tok->cur; tok->inp = tok->buf + curvalid; tok->end = tok->buf + newsize; @@ -1819,7 +1821,7 @@ PyTokenizer_FindEncodingFilename(int fd, PyObject *filename) if (tok->encoding) { encoding = (char *)PyMem_MALLOC(strlen(tok->encoding) + 1); if (encoding) - strcpy(encoding, tok->encoding); + strcpy(encoding, tok->encoding); } PyTokenizer_Free(tok); return encoding; diff --git a/Programs/_freeze_importlib.c b/Programs/_freeze_importlib.c index 13375b0a381955..2e4ccbb154a414 100644 --- a/Programs/_freeze_importlib.c +++ b/Programs/_freeze_importlib.c @@ -76,19 +76,14 @@ main(int argc, char *argv[]) } text[text_size] = '\0'; - PyStatus status; PyConfig config; - - status = PyConfig_InitIsolatedConfig(&config); - if (PyStatus_Exception(status)) { - PyConfig_Clear(&config); - Py_ExitStatusException(status); - } + PyConfig_InitIsolatedConfig(&config); config.site_import = 0; + PyStatus status; status = PyConfig_SetString(&config, &config.program_name, - L"./_freeze_importlib"); + L"./_freeze_importlib"); if (PyStatus_Exception(status)) { PyConfig_Clear(&config); Py_ExitStatusException(status); diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 3e1210e04d8245..b98a38a1ba6783 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1,10 +1,13 @@ -/* FIXME: PEP 587 makes these functions public */ #ifndef Py_BUILD_CORE_MODULE # define Py_BUILD_CORE_MODULE #endif +/* Always enable assertion (even in release mode) */ +#undef NDEBUG + #include -#include "pycore_initconfig.h" /* FIXME: PEP 587 makes these functions public */ +#include "pycore_initconfig.h" /* _PyConfig_InitCompatConfig() */ +#include "pycore_pystate.h" /* _PyRuntime */ #include #include "pythread.h" #include @@ -17,11 +20,12 @@ * Executed via 'EmbeddingTests' in Lib/test/test_capi.py *********************************************************/ +/* Use path starting with "./" avoids a search along the PATH */ +#define PROGRAM_NAME L"./_testembed" + static void _testembed_Py_Initialize(void) { - /* HACK: the "./" at front avoids a search along the PATH in - Modules/getpath.c */ - Py_SetProgramName(L"./_testembed"); + Py_SetProgramName(PROGRAM_NAME); Py_Initialize(); } @@ -326,6 +330,55 @@ static int test_init_initialize_config(void) } +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); + if (PyStatus_Exception(status)) { + PyConfig_Clear(config); + Py_ExitStatusException(status); + } +} + + +static void +config_set_wide_string_list(PyConfig *config, PyWideStringList *list, + Py_ssize_t length, wchar_t **items) +{ + PyStatus status = PyConfig_SetWideStringList(config, list, length, items); + 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 int check_init_compat_config(int preinit) { PyStatus status; @@ -342,12 +395,9 @@ static int check_init_compat_config(int preinit) PyConfig config; _PyConfig_InitCompatConfig(&config); - config.program_name = L"./_testembed"; - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } + config_set_program_name(&config); + init_from_config_clear(&config); dump_config(); Py_Finalize(); @@ -418,8 +468,6 @@ static int test_init_global_config(void) static int test_init_from_config(void) { - PyStatus status; - PyPreConfig preconfig; _PyPreConfig_InitCompatConfig(&preconfig); @@ -430,14 +478,14 @@ static int test_init_from_config(void) Py_UTF8Mode = 0; preconfig.utf8_mode = 1; - status = Py_PreInitialize(&preconfig); + PyStatus status = Py_PreInitialize(&preconfig); if (PyStatus_Exception(status)) { Py_ExitStatusException(status); } - /* Test Py_InitializeFromConfig() */ PyConfig config; _PyConfig_InitCompatConfig(&config); + config.install_signal_handlers = 0; /* FIXME: test use_environment */ @@ -465,34 +513,37 @@ static int test_init_from_config(void) config.malloc_stats = 1; putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix"); - config.pycache_prefix = L"conf_pycache_prefix"; + config_set_string(&config, &config.pycache_prefix, L"conf_pycache_prefix"); Py_SetProgramName(L"./globalvar"); - config.program_name = L"./conf_program_name"; + config_set_string(&config, &config.program_name, L"./conf_program_name"); - static wchar_t* argv[] = { + wchar_t* argv[] = { L"python3", + L"-W", + L"cmdline_warnoption", + L"-X", + L"cmdline_xoption", L"-c", L"pass", L"arg2", }; - config.argv.length = Py_ARRAY_LENGTH(argv); - config.argv.items = argv; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); config.parse_argv = 1; - static wchar_t* xoptions[3] = { - L"xoption1=3", - L"xoption2=", - L"xoption3", + wchar_t* xoptions[3] = { + L"config_xoption1=3", + L"config_xoption2=", + L"config_xoption3", }; - config.xoptions.length = Py_ARRAY_LENGTH(xoptions); - config.xoptions.items = xoptions; + config_set_wide_string_list(&config, &config.xoptions, + Py_ARRAY_LENGTH(xoptions), xoptions); - static wchar_t* warnoptions[1] = { - L"error::ResourceWarning", + wchar_t* warnoptions[1] = { + L"config_warnoption", }; - config.warnoptions.length = Py_ARRAY_LENGTH(warnoptions); - config.warnoptions.items = warnoptions; + config_set_wide_string_list(&config, &config.warnoptions, + Py_ARRAY_LENGTH(warnoptions), warnoptions); /* FIXME: test pythonpath_env */ /* FIXME: test home */ @@ -541,22 +592,20 @@ static int test_init_from_config(void) Force it to 0 through the config. */ config.legacy_windows_stdio = 0; #endif - config.stdio_encoding = L"iso8859-1"; - config.stdio_errors = L"replace"; + config_set_string(&config, &config.stdio_encoding, L"iso8859-1"); + config_set_string(&config, &config.stdio_errors, L"replace"); putenv("PYTHONNOUSERSITE="); Py_NoUserSiteDirectory = 0; config.user_site_directory = 0; - config.check_hash_pycs_mode = L"always"; + config_set_string(&config, &config.check_hash_pycs_mode, L"always"); Py_FrozenFlag = 0; config.pathconfig_warnings = 0; - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } + init_from_config_clear(&config); + dump_config(); Py_Finalize(); return 0; @@ -565,15 +614,12 @@ static int test_init_from_config(void) static int check_init_parse_argv(int parse_argv) { - PyStatus status; - PyConfig config; - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } + PyConfig_InitPythonConfig(&config); + + config.parse_argv = parse_argv; - static wchar_t* argv[] = { + wchar_t* argv[] = { L"./argv0", L"-E", L"-c", @@ -582,15 +628,9 @@ static int check_init_parse_argv(int parse_argv) L"-v", L"arg3", }; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + init_from_config_clear(&config); - config.argv.length = Py_ARRAY_LENGTH(argv); - config.argv.items = argv; - config.parse_argv = parse_argv; - - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } dump_config(); Py_Finalize(); return 0; @@ -652,21 +692,14 @@ static int test_init_compat_env(void) static int test_init_python_env(void) { - PyStatus status; - set_all_env_vars(); PyConfig config; - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } - config.program_name = L"./_testembed"; + PyConfig_InitPythonConfig(&config); + + config_set_program_name(&config); + init_from_config_clear(&config); - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } dump_config(); Py_Finalize(); return 0; @@ -708,26 +741,17 @@ static int test_init_env_dev_mode_alloc(void) static int test_init_isolated_flag(void) { - PyStatus status; - /* Test PyConfig.isolated=1 */ PyConfig config; - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } + PyConfig_InitPythonConfig(&config); Py_IsolatedFlag = 0; config.isolated = 1; - /* Use path starting with "./" avoids a search along the PATH */ - config.program_name = L"./_testembed"; - + config_set_program_name(&config); set_all_env_vars(); - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } + init_from_config_clear(&config); + dump_config(); Py_Finalize(); return 0; @@ -737,26 +761,23 @@ static int test_init_isolated_flag(void) /* PyPreConfig.isolated=1, PyConfig.isolated=0 */ static int test_preinit_isolated1(void) { - PyStatus status; - PyPreConfig preconfig; _PyPreConfig_InitCompatConfig(&preconfig); + preconfig.isolated = 1; - status = Py_PreInitialize(&preconfig); + PyStatus status = Py_PreInitialize(&preconfig); if (PyStatus_Exception(status)) { Py_ExitStatusException(status); } PyConfig config; _PyConfig_InitCompatConfig(&config); - config.program_name = L"./_testembed"; + config_set_program_name(&config); set_all_env_vars(); - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } + init_from_config_clear(&config); + dump_config(); Py_Finalize(); return 0; @@ -766,13 +787,12 @@ static int test_preinit_isolated1(void) /* PyPreConfig.isolated=0, PyConfig.isolated=1 */ static int test_preinit_isolated2(void) { - PyStatus status; - PyPreConfig preconfig; _PyPreConfig_InitCompatConfig(&preconfig); + preconfig.isolated = 0; - status = Py_PreInitialize(&preconfig); + PyStatus status = Py_PreInitialize(&preconfig); if (PyStatus_Exception(status)) { Py_ExitStatusException(status); } @@ -784,14 +804,10 @@ static int test_preinit_isolated2(void) Py_IsolatedFlag = 0; config.isolated = 1; - /* Use path starting with "./" avoids a search along the PATH */ - config.program_name = L"./_testembed"; - + config_set_program_name(&config); set_all_env_vars(); - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } + init_from_config_clear(&config); + dump_config(); Py_Finalize(); return 0; @@ -800,8 +816,6 @@ static int test_preinit_isolated2(void) static int test_preinit_dont_parse_argv(void) { - PyStatus status; - PyPreConfig preconfig; PyPreConfig_InitIsolatedConfig(&preconfig); @@ -814,86 +828,44 @@ static int test_preinit_dont_parse_argv(void) L"-X", L"dev", L"-X", L"utf8", L"script.py"}; - status = Py_PreInitializeFromArgs(&preconfig, Py_ARRAY_LENGTH(argv), argv); + PyStatus status = Py_PreInitializeFromArgs(&preconfig, + Py_ARRAY_LENGTH(argv), argv); if (PyStatus_Exception(status)) { - goto failed; + Py_ExitStatusException(status); } PyConfig config; - - status = PyConfig_InitIsolatedConfig(&config); - if (PyStatus_Exception(status)) { - goto failed; - } + PyConfig_InitIsolatedConfig(&config); config.isolated = 0; /* Pre-initialize implicitly using argv: make sure that -X dev is used to configure the allocation in preinitialization */ - status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv); - if (PyStatus_Exception(status)) { - goto failed; - } - - status = PyConfig_SetString(&config, &config.program_name, - L"./_testembed"); - if (PyStatus_Exception(status)) { - goto failed; - } - - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - goto failed; - } - PyConfig_Clear(&config); + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + config_set_program_name(&config); + init_from_config_clear(&config); dump_config(); Py_Finalize(); return 0; - -failed: - PyConfig_Clear(&config); - Py_ExitStatusException(status); } static int test_preinit_parse_argv(void) { - PyStatus status; PyConfig config; - - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - goto failed; - } + PyConfig_InitPythonConfig(&config); /* 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"}; - status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv); - if (PyStatus_Exception(status)) { - goto failed; - } - - status = PyConfig_SetString(&config, &config.program_name, - L"./_testembed"); - if (PyStatus_Exception(status)) { - goto failed; - } - - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - goto failed; - } - PyConfig_Clear(&config); + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + config_set_program_name(&config); + init_from_config_clear(&config); dump_config(); Py_Finalize(); return 0; - -failed: - PyConfig_Clear(&config); - Py_ExitStatusException(status); } @@ -947,18 +919,10 @@ static int check_preinit_isolated_config(int preinit) } PyConfig config; - status = PyConfig_InitIsolatedConfig(&config); - if (PyStatus_Exception(status)) { - PyConfig_Clear(&config); - Py_ExitStatusException(status); - } - config.program_name = L"./_testembed"; + PyConfig_InitIsolatedConfig(&config); - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - PyConfig_Clear(&config); - Py_ExitStatusException(status); - } + config_set_program_name(&config); + init_from_config_clear(&config); rt_preconfig = &_PyRuntime.preconfig; assert(rt_preconfig->isolated == 1); @@ -984,8 +948,6 @@ static int test_init_isolated_config(void) static int check_init_python_config(int preinit) { - PyStatus status; - /* global configuration variables must be ignored */ set_all_global_config_variables(); Py_IsolatedFlag = 1; @@ -1003,23 +965,18 @@ static int check_init_python_config(int preinit) PyPreConfig preconfig; PyPreConfig_InitPythonConfig(&preconfig); - status = Py_PreInitialize(&preconfig); + PyStatus status = Py_PreInitialize(&preconfig); if (PyStatus_Exception(status)) { Py_ExitStatusException(status); } } PyConfig config; - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } - config.program_name = L"./_testembed"; + PyConfig_InitPythonConfig(&config); + + config_set_program_name(&config); + init_from_config_clear(&config); - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } dump_config(); Py_Finalize(); return 0; @@ -1040,29 +997,23 @@ static int test_init_python_config(void) static int test_init_dont_configure_locale(void) { - PyStatus status; - PyPreConfig preconfig; PyPreConfig_InitPythonConfig(&preconfig); + preconfig.configure_locale = 0; preconfig.coerce_c_locale = 1; preconfig.coerce_c_locale_warn = 1; - status = Py_PreInitialize(&preconfig); + PyStatus status = Py_PreInitialize(&preconfig); if (PyStatus_Exception(status)) { Py_ExitStatusException(status); } PyConfig config; - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } - config.program_name = L"./_testembed"; - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } + PyConfig_InitPythonConfig(&config); + + config_set_program_name(&config); + init_from_config_clear(&config); dump_config(); Py_Finalize(); @@ -1072,20 +1023,15 @@ static int test_init_dont_configure_locale(void) static int test_init_dev_mode(void) { - PyStatus status; PyConfig config; - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } + PyConfig_InitPythonConfig(&config); + putenv("PYTHONFAULTHANDLER="); putenv("PYTHONMALLOC="); config.dev_mode = 1; - config.program_name = L"./_testembed"; - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } + config_set_program_name(&config); + init_from_config_clear(&config); + dump_config(); Py_Finalize(); return 0; @@ -1248,15 +1194,104 @@ static int test_audit_subinterpreter(void) } } -static int test_init_read_set(void) +typedef struct { + const char* expected; + int exit; +} AuditRunCommandTest; + +static int _audit_hook_run(const char *eventName, PyObject *args, void *userData) +{ + AuditRunCommandTest *test = (AuditRunCommandTest*)userData; + if (strcmp(eventName, test->expected)) { + return 0; + } + + if (test->exit) { + PyObject *msg = PyUnicode_FromFormat("detected %s(%R)", eventName, args); + if (msg) { + printf("%s\n", PyUnicode_AsUTF8(msg)); + Py_DECREF(msg); + } + exit(test->exit); + } + + PyErr_Format(PyExc_RuntimeError, "detected %s(%R)", eventName, args); + return -1; +} + +static int test_audit_run_command(void) +{ + AuditRunCommandTest test = {"cpython.run_command"}; + wchar_t *argv[] = {PROGRAM_NAME, L"-c", L"pass"}; + + Py_IgnoreEnvironmentFlag = 0; + PySys_AddAuditHook(_audit_hook_run, (void*)&test); + + return Py_Main(Py_ARRAY_LENGTH(argv), argv); +} + +static int test_audit_run_file(void) +{ + AuditRunCommandTest test = {"cpython.run_file"}; + wchar_t *argv[] = {PROGRAM_NAME, L"filename.py"}; + + Py_IgnoreEnvironmentFlag = 0; + PySys_AddAuditHook(_audit_hook_run, (void*)&test); + + return Py_Main(Py_ARRAY_LENGTH(argv), argv); +} + +static int run_audit_run_test(int argc, wchar_t **argv, void *test) { - PyStatus status; PyConfig config; - status = PyConfig_InitPythonConfig(&config); + PyConfig_InitPythonConfig(&config); + + config.argv.length = argc; + config.argv.items = argv; + config.parse_argv = 1; + config.program_name = argv[0]; + config.interactive = 1; + config.isolated = 0; + config.use_environment = 1; + config.quiet = 1; + + PySys_AddAuditHook(_audit_hook_run, test); + + PyStatus status = Py_InitializeFromConfig(&config); if (PyStatus_Exception(status)) { Py_ExitStatusException(status); } + return Py_RunMain(); +} + +static int test_audit_run_interactivehook(void) +{ + AuditRunCommandTest test = {"cpython.run_interactivehook", 10}; + wchar_t *argv[] = {PROGRAM_NAME}; + return run_audit_run_test(Py_ARRAY_LENGTH(argv), argv, &test); +} + +static int test_audit_run_startup(void) +{ + AuditRunCommandTest test = {"cpython.run_startup", 10}; + wchar_t *argv[] = {PROGRAM_NAME}; + return run_audit_run_test(Py_ARRAY_LENGTH(argv), argv, &test); +} + +static int test_audit_run_stdin(void) +{ + AuditRunCommandTest test = {"cpython.run_stdin"}; + wchar_t *argv[] = {PROGRAM_NAME}; + return run_audit_run_test(Py_ARRAY_LENGTH(argv), argv, &test); +} + +static int test_init_read_set(void) +{ + PyStatus status; + PyConfig config; + PyConfig_InitPythonConfig(&config); + status = PyConfig_SetBytesString(&config, &config.program_name, "./init_read_set"); if (PyStatus_Exception(status)) { @@ -1268,83 +1303,249 @@ static int test_init_read_set(void) goto fail; } + status = PyWideStringList_Insert(&config.module_search_paths, + 1, L"test_path_insert1"); + if (PyStatus_Exception(status)) { + goto fail; + } + status = PyWideStringList_Append(&config.module_search_paths, - L"init_read_set_path"); + L"test_path_append"); if (PyStatus_Exception(status)) { goto fail; } /* override executable computed by PyConfig_Read() */ - status = PyConfig_SetString(&config, &config.executable, L"my_executable"); + config_set_string(&config, &config.executable, L"my_executable"); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; + +fail: + Py_ExitStatusException(status); +} + + +static int test_init_sys_add(void) +{ + PySys_AddXOption(L"sysadd_xoption"); + PySys_AddXOption(L"faulthandler"); + PySys_AddWarnOption(L"ignore:::sysadd_warnoption"); + + PyConfig config; + PyConfig_InitPythonConfig(&config); + + wchar_t* argv[] = { + L"python3", + L"-W", + L"ignore:::cmdline_warnoption", + L"-X", + L"cmdline_xoption", + }; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + config.parse_argv = 1; + + PyStatus status; + status = PyWideStringList_Append(&config.xoptions, + L"config_xoption"); if (PyStatus_Exception(status)) { goto fail; } - status = Py_InitializeFromConfig(&config); - PyConfig_Clear(&config); + status = PyWideStringList_Append(&config.warnoptions, + L"ignore:::config_warnoption"); if (PyStatus_Exception(status)) { goto fail; } + + config_set_program_name(&config); + init_from_config_clear(&config); + dump_config(); Py_Finalize(); return 0; fail: + PyConfig_Clear(&config); Py_ExitStatusException(status); } -wchar_t *init_main_argv[] = { - L"python3", L"-c", - (L"import _testinternalcapi, json; " - L"print(json.dumps(_testinternalcapi.get_configs()))"), - L"arg2"}; +static int test_init_setpath(void) +{ + char *env = getenv("TESTPATH"); + if (!env) { + fprintf(stderr, "missing TESTPATH env var\n"); + return 1; + } + wchar_t *path = Py_DecodeLocale(env, NULL); + if (path == NULL) { + fprintf(stderr, "failed to decode TESTPATH\n"); + return 1; + } + Py_SetPath(path); + PyMem_RawFree(path); + putenv("TESTPATH="); + + Py_Initialize(); + dump_config(); + Py_Finalize(); + return 0; +} -static void configure_init_main(PyConfig *config) +static int test_init_setpath_config(void) { - config->argv.length = Py_ARRAY_LENGTH(init_main_argv); - config->argv.items = init_main_argv; - config->parse_argv = 1; - config->program_name = L"./python3"; + PyPreConfig preconfig; + PyPreConfig_InitPythonConfig(&preconfig); + + /* Explicitly preinitializes with Python preconfiguration to avoid + Py_SetPath() implicit preinitialization with compat preconfiguration. */ + PyStatus status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + char *env = getenv("TESTPATH"); + if (!env) { + fprintf(stderr, "missing TESTPATH env var\n"); + return 1; + } + wchar_t *path = Py_DecodeLocale(env, NULL); + if (path == NULL) { + fprintf(stderr, "failed to decode TESTPATH\n"); + return 1; + } + Py_SetPath(path); + PyMem_RawFree(path); + putenv("TESTPATH="); + + PyConfig config; + PyConfig_InitPythonConfig(&config); + + config_set_string(&config, &config.program_name, L"conf_program_name"); + config_set_string(&config, &config.executable, L"conf_executable"); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; } -static int test_init_run_main(void) +static int test_init_setpythonhome(void) { - PyStatus status; + char *env = getenv("TESTHOME"); + if (!env) { + fprintf(stderr, "missing TESTHOME env var\n"); + return 1; + } + wchar_t *home = Py_DecodeLocale(env, NULL); + if (home == NULL) { + fprintf(stderr, "failed to decode TESTHOME\n"); + return 1; + } + Py_SetPythonHome(home); + PyMem_RawFree(home); + putenv("TESTHOME="); + + Py_Initialize(); + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_init_warnoptions(void) +{ + putenv("PYTHONWARNINGS=ignore:::env1,ignore:::env2"); + + PySys_AddWarnOption(L"ignore:::PySys_AddWarnOption1"); + PySys_AddWarnOption(L"ignore:::PySys_AddWarnOption2"); + PyConfig config; - status = PyConfig_InitPythonConfig(&config); + PyConfig_InitPythonConfig(&config); + + config.dev_mode = 1; + config.bytes_warning = 1; + + config_set_program_name(&config); + + PyStatus status; + status = PyWideStringList_Append(&config.warnoptions, + L"ignore:::PyConfig_BeforeRead"); if (PyStatus_Exception(status)) { Py_ExitStatusException(status); } - configure_init_main(&config); - status = Py_InitializeFromConfig(&config); + wchar_t* argv[] = { + L"python3", + L"-Wignore:::cmdline1", + L"-Wignore:::cmdline2"}; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + config.parse_argv = 1; + + status = PyConfig_Read(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + status = PyWideStringList_Append(&config.warnoptions, + L"ignore:::PyConfig_AfterRead"); if (PyStatus_Exception(status)) { Py_ExitStatusException(status); } + status = PyWideStringList_Insert(&config.warnoptions, + 0, L"ignore:::PyConfig_Insert0"); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + init_from_config_clear(&config); + dump_config(); + Py_Finalize(); + return 0; +} + + +static void configure_init_main(PyConfig *config) +{ + wchar_t* argv[] = { + L"python3", L"-c", + (L"import _testinternalcapi, json; " + L"print(json.dumps(_testinternalcapi.get_configs()))"), + L"arg2"}; + + config->parse_argv = 1; + + config_set_argv(config, Py_ARRAY_LENGTH(argv), argv); + config_set_string(config, &config->program_name, L"./python3"); +} + + +static int test_init_run_main(void) +{ + PyConfig config; + PyConfig_InitPythonConfig(&config); + + configure_init_main(&config); + init_from_config_clear(&config); + return Py_RunMain(); } static int test_init_main(void) { - PyStatus status; PyConfig config; + PyConfig_InitPythonConfig(&config); - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } configure_init_main(&config); config._init_main = 0; - - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } + init_from_config_clear(&config); /* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */ int res = PyRun_SimpleString( @@ -1355,7 +1556,7 @@ static int test_init_main(void) exit(1); } - status = _Py_InitializeMain(); + PyStatus status = _Py_InitializeMain(); if (PyStatus_Exception(status)) { Py_ExitStatusException(status); } @@ -1366,40 +1567,18 @@ static int test_init_main(void) static int test_run_main(void) { - PyStatus status; PyConfig config; - - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - goto failed; - } + PyConfig_InitPythonConfig(&config); wchar_t *argv[] = {L"python3", L"-c", (L"import sys; " L"print(f'Py_RunMain(): sys.argv={sys.argv}')"), L"arg2"}; - status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv); - if (PyStatus_Exception(status)) { - goto failed; - } - - status = PyConfig_SetString(&config, &config.program_name, - L"./python3"); - if (PyStatus_Exception(status)) { - goto failed; - } - - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) { - goto failed; - } - PyConfig_Clear(&config); + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + config_set_string(&config, &config.program_name, L"./python3"); + init_from_config_clear(&config); return Py_RunMain(); - -failed: - PyConfig_Clear(&config); - Py_ExitStatusException(status); } @@ -1454,10 +1633,21 @@ static struct TestCase TestCases[] = { {"test_init_read_set", test_init_read_set}, {"test_init_run_main", test_init_run_main}, {"test_init_main", test_init_main}, + {"test_init_sys_add", test_init_sys_add}, + {"test_init_setpath", test_init_setpath}, + {"test_init_setpath_config", test_init_setpath_config}, + {"test_init_setpythonhome", test_init_setpythonhome}, + {"test_init_warnoptions", test_init_warnoptions}, {"test_run_main", test_run_main}, + {"test_open_code_hook", test_open_code_hook}, {"test_audit", test_audit}, {"test_audit_subinterpreter", test_audit_subinterpreter}, + {"test_audit_run_command", test_audit_run_command}, + {"test_audit_run_file", test_audit_run_file}, + {"test_audit_run_interactivehook", test_audit_run_interactivehook}, + {"test_audit_run_startup", test_audit_run_startup}, + {"test_audit_run_stdin", test_audit_run_stdin}, {NULL, NULL} }; diff --git a/Python/Python-ast.c b/Python/Python-ast.c index dc2b1304f1f20b..f73f035845f8c6 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -476,8 +476,8 @@ _Py_IDENTIFIER(kw_defaults); _Py_IDENTIFIER(kwarg); _Py_IDENTIFIER(defaults); static char *arguments_fields[]={ - "args", "posonlyargs", + "args", "vararg", "kwonlyargs", "kw_defaults", @@ -2573,7 +2573,7 @@ ExceptHandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int } arguments_ty -arguments(asdl_seq * args, asdl_seq * posonlyargs, arg_ty vararg, asdl_seq * +arguments(asdl_seq * posonlyargs, asdl_seq * args, arg_ty vararg, asdl_seq * kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg, asdl_seq * defaults, PyArena *arena) { @@ -2581,8 +2581,8 @@ arguments(asdl_seq * args, asdl_seq * posonlyargs, arg_ty vararg, asdl_seq * p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; - p->args = args; p->posonlyargs = posonlyargs; + p->args = args; p->vararg = vararg; p->kwonlyargs = kwonlyargs; p->kw_defaults = kw_defaults; @@ -3961,14 +3961,14 @@ ast2obj_arguments(void* _o) result = PyType_GenericNew(arguments_type, NULL, NULL); if (!result) return NULL; - value = ast2obj_list(o->args, ast2obj_arg); + value = ast2obj_list(o->posonlyargs, ast2obj_arg); if (!value) goto failed; - if (_PyObject_SetAttrId(result, &PyId_args, value) == -1) + if (_PyObject_SetAttrId(result, &PyId_posonlyargs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(o->posonlyargs, ast2obj_arg); + value = ast2obj_list(o->args, ast2obj_arg); if (!value) goto failed; - if (_PyObject_SetAttrId(result, &PyId_posonlyargs, value) == -1) + if (_PyObject_SetAttrId(result, &PyId_args, value) == -1) goto failed; Py_DECREF(value); value = ast2obj_arg(o->vararg); @@ -8288,19 +8288,19 @@ int obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena) { PyObject* tmp = NULL; - asdl_seq* args; asdl_seq* posonlyargs; + asdl_seq* args; arg_ty vararg; asdl_seq* kwonlyargs; asdl_seq* kw_defaults; arg_ty kwarg; asdl_seq* defaults; - if (_PyObject_LookupAttrId(obj, &PyId_args, &tmp) < 0) { + if (_PyObject_LookupAttrId(obj, &PyId_posonlyargs, &tmp) < 0) { return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from arguments"); + PyErr_SetString(PyExc_TypeError, "required field \"posonlyargs\" missing from arguments"); return 1; } else { @@ -8308,29 +8308,29 @@ obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena) Py_ssize_t len; Py_ssize_t i; if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "arguments field \"args\" must be a list, not a %.200s", tmp->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, "arguments field \"posonlyargs\" must be a list, not a %.200s", tmp->ob_type->tp_name); goto failed; } len = PyList_GET_SIZE(tmp); - args = _Py_asdl_seq_new(len, arena); - if (args == NULL) goto failed; + posonlyargs = _Py_asdl_seq_new(len, arena); + if (posonlyargs == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; res = obj2ast_arg(PyList_GET_ITEM(tmp, i), &val, arena); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "arguments field \"args\" changed size during iteration"); + PyErr_SetString(PyExc_RuntimeError, "arguments field \"posonlyargs\" changed size during iteration"); goto failed; } - asdl_seq_SET(args, i, val); + asdl_seq_SET(posonlyargs, i, val); } Py_CLEAR(tmp); } - if (_PyObject_LookupAttrId(obj, &PyId_posonlyargs, &tmp) < 0) { + if (_PyObject_LookupAttrId(obj, &PyId_args, &tmp) < 0) { return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"posonlyargs\" missing from arguments"); + PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from arguments"); return 1; } else { @@ -8338,21 +8338,21 @@ obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena) Py_ssize_t len; Py_ssize_t i; if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "arguments field \"posonlyargs\" must be a list, not a %.200s", tmp->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, "arguments field \"args\" must be a list, not a %.200s", tmp->ob_type->tp_name); goto failed; } len = PyList_GET_SIZE(tmp); - posonlyargs = _Py_asdl_seq_new(len, arena); - if (posonlyargs == NULL) goto failed; + args = _Py_asdl_seq_new(len, arena); + if (args == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; res = obj2ast_arg(PyList_GET_ITEM(tmp, i), &val, arena); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "arguments field \"posonlyargs\" changed size during iteration"); + PyErr_SetString(PyExc_RuntimeError, "arguments field \"args\" changed size during iteration"); goto failed; } - asdl_seq_SET(posonlyargs, i, val); + asdl_seq_SET(args, i, val); } Py_CLEAR(tmp); } @@ -8472,7 +8472,7 @@ obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = arguments(args, posonlyargs, vararg, kwonlyargs, kw_defaults, kwarg, + *out = arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, defaults, arena); return 0; failed: @@ -8991,12 +8991,6 @@ PyObject* PyAST_mod2obj(mod_ty t) /* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) { - return PyAST_obj2mod_ex(ast, arena, mode, PY_MINOR_VERSION); -} - -mod_ty PyAST_obj2mod_ex(PyObject* ast, PyArena* arena, int mode, int feature_version) -{ - mod_ty res; PyObject *req_type[3]; char *req_name[] = {"Module", "Expression", "Interactive"}; int isinstance; @@ -9022,6 +9016,8 @@ mod_ty PyAST_obj2mod_ex(PyObject* ast, PyArena* arena, int mode, int feature_ver req_name[mode], Py_TYPE(ast)->tp_name); return NULL; } + + mod_ty res = NULL; if (obj2ast_mod(ast, &res, arena) != 0) return NULL; else diff --git a/Python/_warnings.c b/Python/_warnings.c index 0b192580e1073e..e02d28305126df 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1305,7 +1305,7 @@ _PyErr_WarnUnawaitedCoroutine(PyObject *coro) } PyDoc_STRVAR(warn_explicit_doc, -"Low-level inferface to warnings functionality."); +"Low-level interface to warnings functionality."); static PyMethodDef warnings_functions[] = { WARNINGS_WARN_METHODDEF diff --git a/Python/ast.c b/Python/ast.c index df9242977e3f21..2031b88359363a 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -1688,7 +1688,7 @@ ast_for_arguments(struct compiling *c, const node *n) return NULL; } } - return arguments(posargs, posonlyargs, vararg, kwonlyargs, kwdefaults, kwarg, posdefaults, c->c_arena); + return arguments(posonlyargs, posargs, vararg, kwonlyargs, kwdefaults, kwarg, posdefaults, c->c_arena); } static expr_ty @@ -1747,8 +1747,10 @@ ast_for_decorator(struct compiling *c, const node *n) name_expr = NULL; } else if (NCH(n) == 5) { /* Call with no arguments */ - d = Call(name_expr, NULL, NULL, LINENO(n), - n->n_col_offset, n->n_end_lineno, n->n_end_col_offset, c->c_arena); + d = Call(name_expr, NULL, NULL, + name_expr->lineno, name_expr->col_offset, + CHILD(n, 3)->n_end_lineno, CHILD(n, 3)->n_end_col_offset, + c->c_arena); if (!d) return NULL; name_expr = NULL; @@ -2645,7 +2647,7 @@ ast_for_binop(struct compiling *c, const node *n) return NULL; tmp_result = BinOp(result, newoperator, tmp, - LINENO(next_oper), next_oper->n_col_offset, + LINENO(n), n->n_col_offset, CHILD(n, i * 2 + 2)->n_end_lineno, CHILD(n, i * 2 + 2)->n_end_col_offset, c->c_arena); @@ -4674,12 +4676,12 @@ warn_invalid_escape_sequence(struct compiling *c, const node *n, if (msg == NULL) { return -1; } - if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, + if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg, c->c_filename, LINENO(n), NULL, NULL) < 0) { - if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { - /* Replace the SyntaxWarning exception with a SyntaxError + if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { + /* Replace the DeprecationWarning exception with a SyntaxError to get a more accurate error report */ PyErr_Clear(); ast_error(c, n, "%U", msg); @@ -4845,7 +4847,6 @@ fstring_compile_expr(const char *expr_start, const char *expr_end, struct compiling *c, const node *n) { - PyCompilerFlags cf; node *mod_n; mod_ty mod; char *str; @@ -4887,8 +4888,8 @@ fstring_compile_expr(const char *expr_start, const char *expr_end, str[len+1] = ')'; str[len+2] = 0; + PyCompilerFlags cf = _PyCompilerFlags_INIT; cf.cf_flags = PyCF_ONLY_AST; - cf.cf_feature_version = PY_MINOR_VERSION; mod_n = PyParser_SimpleParseStringFlagsFilename(str, "", Py_eval_input, 0); if (!mod_n) { @@ -5360,7 +5361,7 @@ typedef struct { doubling the number allocated each time. Note that the f-string f'{0}a{1}' contains 3 expr_ty's: 2 FormattedValue's, and one Constant for the literal 'a'. So you add expr_ty's about twice as - fast as you add exressions in an f-string. */ + fast as you add expressions in an f-string. */ Py_ssize_t allocated; /* Number we've allocated. */ Py_ssize_t size; /* Number we've used. */ diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 56d882d387eeed..33f969094e7d15 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -261,7 +261,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, } PyDoc_STRVAR(build_class_doc, -"__build_class__(func, name, *bases, metaclass=None, **kwds) -> class\n\ +"__build_class__(func, name, /, *bases, [metaclass], **kwds) -> class\n\ \n\ Internal helper function used by the class statement."); @@ -482,6 +482,11 @@ builtin_breakpoint(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb PyErr_SetString(PyExc_RuntimeError, "lost sys.breakpointhook"); return NULL; } + + if (PySys_Audit("builtins.breakpoint", "O", hook) < 0) { + return NULL; + } + Py_INCREF(hook); PyObject *retval = _PyObject_Vectorcall(hook, args, nargs, keywords); Py_DECREF(hook); @@ -696,7 +701,8 @@ compile as builtin_compile flags: int = 0 dont_inherit: bool(accept={int}) = False optimize: int = -1 - feature_version: int = -1 + * + _feature_version as feature_version: int = -1 Compile source into a code object that can be executed by exec() or eval(). @@ -716,18 +722,17 @@ 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=5fcc30651a6acaa9]*/ +/*[clinic end generated code: output=b0c09c84f116d3d7 input=40171fb92c1d580d]*/ { PyObject *source_copy; const char *str; int compile_mode = -1; int is_ast; - PyCompilerFlags cf; int start[] = {Py_file_input, Py_eval_input, Py_single_input, Py_func_type_input}; PyObject *result; + PyCompilerFlags cf = _PyCompilerFlags_INIT; cf.cf_flags = flags | PyCF_SOURCE_IS_UTF8; - cf.cf_feature_version = PY_MINOR_VERSION; if (feature_version >= 0 && (flags & PyCF_ONLY_AST)) { cf.cf_feature_version = feature_version; } @@ -888,7 +893,6 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, { PyObject *result, *source_copy; const char *str; - PyCompilerFlags cf; if (locals != Py_None && !PyMapping_Check(locals)) { PyErr_SetString(PyExc_TypeError, "locals must be a mapping"); @@ -940,8 +944,8 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, return PyEval_EvalCode(source, globals, locals); } + PyCompilerFlags cf = _PyCompilerFlags_INIT; cf.cf_flags = PyCF_SOURCE_IS_UTF8; - cf.cf_feature_version = PY_MINOR_VERSION; str = _Py_SourceAsString(source, "eval", "string, bytes or code", &cf, &source_copy); if (str == NULL) return NULL; @@ -1031,9 +1035,8 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, else { PyObject *source_copy; const char *str; - PyCompilerFlags cf; + PyCompilerFlags cf = _PyCompilerFlags_INIT; cf.cf_flags = PyCF_SOURCE_IS_UTF8; - cf.cf_feature_version = PY_MINOR_VERSION; str = _Py_SourceAsString(source, "exec", "string, bytes or code", &cf, &source_copy); @@ -1794,22 +1797,22 @@ builtin_ord(PyObject *module, PyObject *c) /*[clinic input] pow as builtin_pow - x: object - y: object - z: object = None - / + base: object + exp: object + mod: object = None -Equivalent to x**y (with two arguments) or x**y % z (with three arguments) +Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. [clinic start generated code]*/ static PyObject * -builtin_pow_impl(PyObject *module, PyObject *x, PyObject *y, PyObject *z) -/*[clinic end generated code: output=50a14d5d130d404b input=653d57d38d41fc07]*/ +builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp, + PyObject *mod) +/*[clinic end generated code: output=3ca1538221bbf15f input=435dbd48a12efb23]*/ { - return PyNumber_Power(x, y, z); + return PyNumber_Power(base, exp, mod); } @@ -2144,7 +2147,7 @@ builtin_repr(PyObject *module, PyObject *obj) round as builtin_round number: object - ndigits: object = NULL + ndigits: object = None Round a number to a given precision in decimal digits. @@ -2154,7 +2157,7 @@ the return value has the same type as the number. ndigits may be negative. static PyObject * builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits) -/*[clinic end generated code: output=ff0d9dd176c02ede input=854bc3a217530c3d]*/ +/*[clinic end generated code: output=ff0d9dd176c02ede input=275678471d7aca15]*/ { PyObject *round, *result; @@ -2172,7 +2175,7 @@ builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits) return NULL; } - if (ndigits == NULL || ndigits == Py_None) + if (ndigits == Py_None) result = _PyObject_CallNoArg(round); else result = PyObject_CallFunctionObjArgs(round, ndigits, NULL); @@ -2253,16 +2256,12 @@ builtin_vars(PyObject *self, PyObject *args) return NULL; if (v == NULL) { d = PyEval_GetLocals(); - if (d == NULL) - return NULL; - Py_INCREF(d); + Py_XINCREF(d); } else { - d = _PyObject_GetAttrId(v, &PyId___dict__); - if (d == NULL) { + if (_PyObject_LookupAttrId(v, &PyId___dict__, &d) == 0) { PyErr_SetString(PyExc_TypeError, "vars() argument must have __dict__ attribute"); - return NULL; } } return d; @@ -2546,10 +2545,6 @@ zip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *item = PyTuple_GET_ITEM(args, i); PyObject *it = PyObject_GetIter(item); if (it == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - PyErr_Format(PyExc_TypeError, - "zip argument #%zd must support iteration", - i+1); Py_DECREF(ittuple); return NULL; } @@ -2653,7 +2648,7 @@ static PyMethodDef zip_methods[] = { }; PyDoc_STRVAR(zip_doc, -"zip(iter1 [,iter2 [...]]) --> zip object\n\ +"zip(*iterables) --> zip object\n\ \n\ Return a zip object whose .__next__() method returns a tuple where\n\ the i-th element comes from the i-th iterable argument. The .__next__()\n\ diff --git a/Python/ceval.c b/Python/ceval.c index 7063647d584f65..3306fb9728e8cd 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2944,8 +2944,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } case TARGET(MAP_ADD): { - PyObject *key = TOP(); - PyObject *value = SECOND(); + PyObject *value = TOP(); + PyObject *key = SECOND(); PyObject *map; int err; STACK_SHRINK(2); @@ -4943,7 +4943,7 @@ trace_call_function(PyThreadState *tstate, { PyObject *x; if (PyCFunction_Check(func)) { - C_TRACE(x, _PyCFunction_Vectorcall(func, args, nargs, kwnames)); + C_TRACE(x, _PyObject_Vectorcall(func, args, nargs, kwnames)); return x; } else if (Py_TYPE(func) == &PyMethodDescr_Type && nargs > 0) { @@ -4959,9 +4959,9 @@ trace_call_function(PyThreadState *tstate, if (func == NULL) { return NULL; } - C_TRACE(x, _PyCFunction_Vectorcall(func, - args+1, nargs-1, - kwnames)); + C_TRACE(x, _PyObject_Vectorcall(func, + args+1, nargs-1, + kwnames)); Py_DECREF(func); return x; } @@ -5023,10 +5023,10 @@ do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject return NULL; } - C_TRACE(result, _PyCFunction_FastCallDict(func, - &_PyTuple_ITEMS(callargs)[1], - nargs - 1, - kwdict)); + C_TRACE(result, _PyObject_FastCallDict(func, + &_PyTuple_ITEMS(callargs)[1], + nargs - 1, + kwdict)); Py_DECREF(func); return result; } @@ -5236,10 +5236,16 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name) PyErr_SetImportError(errmsg, pkgname, NULL); } else { - errmsg = PyUnicode_FromFormat( - "cannot import name %R from %R (%S)", - name, pkgname_or_unknown, pkgpath - ); + _Py_IDENTIFIER(__spec__); + PyObject *spec = _PyObject_GetAttrId(v, &PyId___spec__); + const char *fmt = + _PyModuleSpec_IsInitializing(spec) ? + "cannot import name %R from partially initialized module %R " + "(most likely due to a circular import) (%S)" : + "cannot import name %R from %R (%S)"; + Py_XDECREF(spec); + + errmsg = PyUnicode_FromFormat(fmt, name, pkgname_or_unknown, pkgpath); /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ PyErr_SetImportError(errmsg, pkgname, pkgpath); } diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h index 0ed11bceeb87e2..d15af1f7f377c6 100644 --- a/Python/clinic/bltinmodule.c.h +++ b/Python/clinic/bltinmodule.c.h @@ -102,7 +102,7 @@ builtin_format(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto skip_optional; } if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("format", 2, "str", args[1]); + _PyArg_BadArgument("format", "argument 2", "str", args[1]); goto exit; } if (PyUnicode_READY(args[1]) == -1) { @@ -151,7 +151,7 @@ builtin_chr(PyObject *module, PyObject *arg) PyDoc_STRVAR(builtin_compile__doc__, "compile($module, /, source, filename, mode, flags=0,\n" -" dont_inherit=False, optimize=-1, feature_version=-1)\n" +" dont_inherit=False, optimize=-1, *, _feature_version=-1)\n" "--\n" "\n" "Compile source into a code object that can be executed by exec() or eval().\n" @@ -179,7 +179,7 @@ static PyObject * builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", "feature_version", NULL}; + static const char * const _keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", "_feature_version", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0}; PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; @@ -191,7 +191,7 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj int optimize = -1; int feature_version = -1; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 7, 0, argsbuf); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 6, 0, argsbuf); if (!args) { goto exit; } @@ -200,7 +200,7 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto exit; } if (!PyUnicode_Check(args[2])) { - _PyArg_BadArgument("compile", 3, "str", args[2]); + _PyArg_BadArgument("compile", "argument 'mode'", "str", args[2]); goto exit; } Py_ssize_t mode_length; @@ -257,6 +257,10 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_pos; } } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } if (PyFloat_Check(args[6])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -266,7 +270,7 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (feature_version == -1 && PyErr_Occurred()) { goto exit; } -skip_optional_pos: +skip_optional_kwonly: return_value = builtin_compile_impl(module, source, filename, mode, flags, dont_inherit, optimize, feature_version); exit: @@ -604,39 +608,45 @@ PyDoc_STRVAR(builtin_ord__doc__, {"ord", (PyCFunction)builtin_ord, METH_O, builtin_ord__doc__}, PyDoc_STRVAR(builtin_pow__doc__, -"pow($module, x, y, z=None, /)\n" +"pow($module, /, base, exp, mod=None)\n" "--\n" "\n" -"Equivalent to x**y (with two arguments) or x**y % z (with three arguments)\n" +"Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments\n" "\n" "Some types, such as ints, are able to use a more efficient algorithm when\n" "invoked using the three argument form."); #define BUILTIN_POW_METHODDEF \ - {"pow", (PyCFunction)(void(*)(void))builtin_pow, METH_FASTCALL, builtin_pow__doc__}, + {"pow", (PyCFunction)(void(*)(void))builtin_pow, METH_FASTCALL|METH_KEYWORDS, builtin_pow__doc__}, static PyObject * -builtin_pow_impl(PyObject *module, PyObject *x, PyObject *y, PyObject *z); +builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp, + PyObject *mod); static PyObject * -builtin_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +builtin_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - PyObject *x; - PyObject *y; - PyObject *z = Py_None; - - if (!_PyArg_CheckPositional("pow", nargs, 2, 3)) { + static const char * const _keywords[] = {"base", "exp", "mod", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "pow", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *base; + PyObject *exp; + PyObject *mod = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { goto exit; } - x = args[0]; - y = args[1]; - if (nargs < 3) { - goto skip_optional; + base = args[0]; + exp = args[1]; + if (!noptargs) { + goto skip_optional_pos; } - z = args[2]; -skip_optional: - return_value = builtin_pow_impl(module, x, y, z); + mod = args[2]; +skip_optional_pos: + return_value = builtin_pow_impl(module, base, exp, mod); exit: return return_value; @@ -715,7 +725,7 @@ builtin_round(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *number; - PyObject *ndigits = NULL; + PyObject *ndigits = Py_None; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { @@ -845,4 +855,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=3f690311ac556c31 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=29686a89b739d600 input=a9049054013a1b77]*/ diff --git a/Python/clinic/context.c.h b/Python/clinic/context.c.h index eedfc88654b624..2ac8bf7c0b8ca0 100644 --- a/Python/clinic/context.c.h +++ b/Python/clinic/context.c.h @@ -115,7 +115,7 @@ _contextvars_Context_copy(PyContext *self, PyObject *Py_UNUSED(ignored)) } PyDoc_STRVAR(_contextvars_ContextVar_get__doc__, -"get($self, default=None, /)\n" +"get($self, default=, /)\n" "--\n" "\n" "Return a value for the context variable for the current context.\n" @@ -177,4 +177,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=a86b66e1516c25d4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f2e42f34e358e179 input=a9049054013a1b77]*/ diff --git a/Python/clinic/import.c.h b/Python/clinic/import.c.h index 05e3106bb39af0..e4867f34d4ef16 100644 --- a/Python/clinic/import.c.h +++ b/Python/clinic/import.c.h @@ -92,12 +92,12 @@ _imp__fix_co_filename(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyObject_TypeCheck(args[0], &PyCode_Type)) { - _PyArg_BadArgument("_fix_co_filename", 1, (&PyCode_Type)->tp_name, args[0]); + _PyArg_BadArgument("_fix_co_filename", "argument 1", (&PyCode_Type)->tp_name, args[0]); goto exit; } code = (PyCodeObject *)args[0]; if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("_fix_co_filename", 2, "str", args[1]); + _PyArg_BadArgument("_fix_co_filename", "argument 2", "str", args[1]); goto exit; } if (PyUnicode_READY(args[1]) == -1) { @@ -156,7 +156,7 @@ _imp_init_frozen(PyObject *module, PyObject *arg) PyObject *name; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("init_frozen", 0, "str", arg); + _PyArg_BadArgument("init_frozen", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -188,7 +188,7 @@ _imp_get_frozen_object(PyObject *module, PyObject *arg) PyObject *name; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("get_frozen_object", 0, "str", arg); + _PyArg_BadArgument("get_frozen_object", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -220,7 +220,7 @@ _imp_is_frozen_package(PyObject *module, PyObject *arg) PyObject *name; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("is_frozen_package", 0, "str", arg); + _PyArg_BadArgument("is_frozen_package", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -252,7 +252,7 @@ _imp_is_builtin(PyObject *module, PyObject *arg) PyObject *name; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("is_builtin", 0, "str", arg); + _PyArg_BadArgument("is_builtin", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -284,7 +284,7 @@ _imp_is_frozen(PyObject *module, PyObject *arg) PyObject *name; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("is_frozen", 0, "str", arg); + _PyArg_BadArgument("is_frozen", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -300,7 +300,7 @@ _imp_is_frozen(PyObject *module, PyObject *arg) #if defined(HAVE_DYNAMIC_LOADING) PyDoc_STRVAR(_imp_create_dynamic__doc__, -"create_dynamic($module, spec, file=None, /)\n" +"create_dynamic($module, spec, file=, /)\n" "--\n" "\n" "Create an extension module."); @@ -433,7 +433,7 @@ _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto exit; } if (!PyBuffer_IsContiguous(&source, 'C')) { - _PyArg_BadArgument("source_hash", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("source_hash", "argument 'source'", "contiguous buffer", args[1]); goto exit; } return_value = _imp_source_hash_impl(module, key, &source); @@ -454,4 +454,4 @@ _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb #ifndef _IMP_EXEC_DYNAMIC_METHODDEF #define _IMP_EXEC_DYNAMIC_METHODDEF #endif /* !defined(_IMP_EXEC_DYNAMIC_METHODDEF) */ -/*[clinic end generated code: output=b51244770fdcf4b8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3dc495e9c64d944e input=a9049054013a1b77]*/ diff --git a/Python/clinic/marshal.c.h b/Python/clinic/marshal.c.h index ab4575340e2565..05d4830c4ab313 100644 --- a/Python/clinic/marshal.c.h +++ b/Python/clinic/marshal.c.h @@ -152,7 +152,7 @@ marshal_loads(PyObject *module, PyObject *arg) goto exit; } if (!PyBuffer_IsContiguous(&bytes, 'C')) { - _PyArg_BadArgument("loads", 0, "contiguous buffer", arg); + _PyArg_BadArgument("loads", "argument", "contiguous buffer", arg); goto exit; } return_value = marshal_loads_impl(module, &bytes); @@ -165,4 +165,4 @@ marshal_loads(PyObject *module, PyObject *arg) return return_value; } -/*[clinic end generated code: output=ae2bca1aa239e095 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a859dabe8b0afeb6 input=a9049054013a1b77]*/ diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index 6f248ff18d9d7f..d2d1503926205d 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -135,7 +135,7 @@ static PyObject * sys_exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *status = NULL; + PyObject *status = Py_None; if (!_PyArg_CheckPositional("exit", nargs, 0, 1)) { goto exit; @@ -228,7 +228,7 @@ sys_intern(PyObject *module, PyObject *arg) PyObject *s; if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("intern", 0, "str", arg); + _PyArg_BadArgument("intern", "argument", "str", arg); goto exit; } if (PyUnicode_READY(arg) == -1) { @@ -362,9 +362,15 @@ sys_setswitchinterval(PyObject *module, PyObject *arg) PyObject *return_value = NULL; double interval; - interval = PyFloat_AsDouble(arg); - if (PyErr_Occurred()) { - goto exit; + if (PyFloat_CheckExact(arg)) { + interval = PyFloat_AS_DOUBLE(arg); + } + else + { + interval = PyFloat_AsDouble(arg); + if (interval == -1.0 && PyErr_Occurred()) { + goto exit; + } } return_value = sys_setswitchinterval_impl(module, interval); @@ -925,7 +931,7 @@ sys_call_tracing(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } func = args[0]; if (!PyTuple_Check(args[1])) { - _PyArg_BadArgument("call_tracing", 2, "tuple", args[1]); + _PyArg_BadArgument("call_tracing", "argument 2", "tuple", args[1]); goto exit; } funcargs = args[1]; @@ -1082,4 +1088,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=43c4fde7b5783d8d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=273f9cec8bfcab91 input=a9049054013a1b77]*/ diff --git a/Python/clinic/traceback.c.h b/Python/clinic/traceback.c.h index 2815f65d3dd1c0..04daf2a3766988 100644 --- a/Python/clinic/traceback.c.h +++ b/Python/clinic/traceback.c.h @@ -32,7 +32,7 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } tb_next = fastargs[0]; if (!PyObject_TypeCheck(fastargs[1], &PyFrame_Type)) { - _PyArg_BadArgument("TracebackType", 2, (&PyFrame_Type)->tp_name, fastargs[1]); + _PyArg_BadArgument("TracebackType", "argument 'tb_frame'", (&PyFrame_Type)->tp_name, fastargs[1]); goto exit; } tb_frame = (PyFrameObject *)fastargs[1]; @@ -59,4 +59,4 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=7e4c0e252d0973b0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3def6c06248feed8 input=a9049054013a1b77]*/ diff --git a/Python/compile.c b/Python/compile.c index 9e4a2094ac9b92..a512e9cbd13a16 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -81,7 +81,7 @@ It's called a frame block to distinguish it from a basic block in the compiler IR. */ -enum fblocktype { WHILE_LOOP, FOR_LOOP, EXCEPT, FINALLY_TRY, FINALLY_END, +enum fblocktype { WHILE_LOOP, FOR_LOOP, EXCEPT, FINALLY_TRY, FINALLY_TRY2, FINALLY_END, WITH, ASYNC_WITH, HANDLER_CLEANUP }; struct fblockinfo { @@ -161,6 +161,11 @@ struct compiler { int c_optimize; /* optimization level */ int c_interactive; /* true if in interactive mode */ int c_nestlevel; + int c_do_not_emit_bytecode; /* The compiler won't emit any bytecode + if this value is different from zero. + This can be used to temporarily visit + nodes without emitting bytecode to + check only errors. */ PyObject *c_const_cache; /* Python dict holding all constants, including names tuple */ @@ -309,7 +314,7 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, { struct compiler c; PyCodeObject *co = NULL; - PyCompilerFlags local_flags; + PyCompilerFlags local_flags = _PyCompilerFlags_INIT; int merged; PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; @@ -332,8 +337,6 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, if (c.c_future == NULL) goto finally; if (!flags) { - local_flags.cf_flags = 0; - local_flags.cf_feature_version = PY_MINOR_VERSION; flags = &local_flags; } merged = c.c_future->ff_features | flags->cf_flags; @@ -342,6 +345,7 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, c.c_flags = flags; c.c_optimize = (optimize == -1) ? config->optimization_level : optimize; c.c_nestlevel = 0; + c.c_do_not_emit_bytecode = 0; if (!_PyAST_Optimize(mod, arena, c.c_optimize)) { goto finally; @@ -1154,6 +1158,9 @@ compiler_addop(struct compiler *c, int opcode) struct instr *i; int off; assert(!HAS_ARG(opcode)); + if (c->c_do_not_emit_bytecode) { + return 1; + } off = compiler_next_instr(c, c->u->u_curblock); if (off < 0) return 0; @@ -1307,6 +1314,10 @@ merge_consts_recursive(struct compiler *c, PyObject *o) static Py_ssize_t compiler_add_const(struct compiler *c, PyObject *o) { + if (c->c_do_not_emit_bytecode) { + return 0; + } + PyObject *key = merge_consts_recursive(c, o); if (key == NULL) { return -1; @@ -1320,6 +1331,10 @@ compiler_add_const(struct compiler *c, PyObject *o) static int compiler_addop_load_const(struct compiler *c, PyObject *o) { + if (c->c_do_not_emit_bytecode) { + return 1; + } + Py_ssize_t arg = compiler_add_const(c, o); if (arg < 0) return 0; @@ -1330,6 +1345,10 @@ static int compiler_addop_o(struct compiler *c, int opcode, PyObject *dict, PyObject *o) { + if (c->c_do_not_emit_bytecode) { + return 1; + } + Py_ssize_t arg = compiler_add_o(c, dict, o); if (arg < 0) return 0; @@ -1341,6 +1360,11 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, PyObject *o) { Py_ssize_t arg; + + if (c->c_do_not_emit_bytecode) { + return 1; + } + PyObject *mangled = _Py_Mangle(c->u->u_private, o); if (!mangled) return 0; @@ -1361,6 +1385,10 @@ compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg) struct instr *i; int off; + if (c->c_do_not_emit_bytecode) { + return 1; + } + /* oparg value is unsigned, but a signed C int is usually used to store it in the C code (like Python/ceval.c). @@ -1387,6 +1415,10 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) struct instr *i; int off; + if (c->c_do_not_emit_bytecode) { + return 1; + } + assert(HAS_ARG(opcode)); assert(b != NULL); off = compiler_next_instr(c, c->u->u_curblock); @@ -1521,6 +1553,17 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) } \ } +/* These macros allows to check only for errors and not emmit bytecode + * while visiting nodes. +*/ + +#define BEGIN_DO_NOT_EMIT_BYTECODE { \ + c->c_do_not_emit_bytecode++; + +#define END_DO_NOT_EMIT_BYTECODE \ + c->c_do_not_emit_bytecode--; \ +} + /* Search if variable annotations are present statically in a block. */ static int @@ -1621,7 +1664,12 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, return 1; case FINALLY_END: + info->fb_exit = NULL; ADDOP_I(c, POP_FINALLY, preserve_tos); + if (preserve_tos) { + ADDOP(c, ROT_TWO); + } + ADDOP(c, POP_TOP); return 1; case FOR_LOOP: @@ -1641,6 +1689,19 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); return 1; + case FINALLY_TRY2: + ADDOP(c, POP_BLOCK); + if (preserve_tos) { + ADDOP(c, ROT_TWO); + ADDOP(c, POP_TOP); + ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); + } + else { + ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); + ADDOP(c, POP_TOP); + } + return 1; + case WITH: case ASYNC_WITH: ADDOP(c, POP_BLOCK); @@ -1688,7 +1749,7 @@ compiler_body(struct compiler *c, asdl_seq *stmts) /* Set current line number to the line number of first statement. This way line number for SETUP_ANNOTATIONS will always coincide with the line number of first "real" statement in module. - If body is empy, then lineno will be set later in assemble. */ + If body is empty, then lineno will be set later in assemble. */ if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && !c->u->u_lineno && asdl_seq_LEN(stmts)) { st = (stmt_ty)asdl_seq_GET(stmts, 0); @@ -2548,13 +2609,23 @@ compiler_if(struct compiler *c, stmt_ty s) return 0; constant = expr_constant(s->v.If.test); - /* constant = 0: "if 0" Leave the optimizations to - * the pephole optimizer to check for syntax errors - * in the block. + /* constant = 0: "if 0" * constant = 1: "if 1", "if 2", ... * constant = -1: rest */ - if (constant == 1) { + if (constant == 0) { + BEGIN_DO_NOT_EMIT_BYTECODE VISIT_SEQ(c, stmt, s->v.If.body); + END_DO_NOT_EMIT_BYTECODE + if (s->v.If.orelse) { + VISIT_SEQ(c, stmt, s->v.If.orelse); + } + } else if (constant == 1) { + VISIT_SEQ(c, stmt, s->v.If.body); + if (s->v.If.orelse) { + BEGIN_DO_NOT_EMIT_BYTECODE + VISIT_SEQ(c, stmt, s->v.If.orelse); + END_DO_NOT_EMIT_BYTECODE + } } else { if (asdl_seq_LEN(s->v.If.orelse)) { next = compiler_new_block(c); @@ -2664,8 +2735,12 @@ compiler_while(struct compiler *c, stmt_ty s) int constant = expr_constant(s->v.While.test); if (constant == 0) { - if (s->v.While.orelse) + BEGIN_DO_NOT_EMIT_BYTECODE + VISIT_SEQ(c, stmt, s->v.While.body); + END_DO_NOT_EMIT_BYTECODE + if (s->v.While.orelse) { VISIT_SEQ(c, stmt, s->v.While.orelse); + } return 1; } loop = compiler_new_block(c); @@ -2812,17 +2887,47 @@ compiler_continue(struct compiler *c) static int compiler_try_finally(struct compiler *c, stmt_ty s) { - basicblock *body, *end; + basicblock *start, *newcurblock, *body, *end; + int break_finally = 1; body = compiler_new_block(c); end = compiler_new_block(c); if (body == NULL || end == NULL) return 0; + start = c->u->u_curblock; + + /* `finally` block. Compile it first to determine if any of "break", + "continue" or "return" are used in it. */ + compiler_use_next_block(c, end); + if (!compiler_push_fblock(c, FINALLY_END, end, end)) + return 0; + VISIT_SEQ(c, stmt, s->v.Try.finalbody); + ADDOP(c, END_FINALLY); + break_finally = (c->u->u_fblock[c->u->u_nfblocks - 1].fb_exit == NULL); + if (break_finally) { + /* Pops a placeholder. See below */ + ADDOP(c, POP_TOP); + } + compiler_pop_fblock(c, FINALLY_END, end); + + newcurblock = c->u->u_curblock; + c->u->u_curblock = start; + start->b_next = NULL; + /* `try` block */ + c->u->u_lineno_set = 0; + c->u->u_lineno = s->lineno; + c->u->u_col_offset = s->col_offset; + if (break_finally) { + /* Pushes a placeholder for the value of "return" in the "try" block + to balance the stack for "break", "continue" and "return" in + the "finally" block. */ + ADDOP_LOAD_CONST(c, Py_None); + } ADDOP_JREL(c, SETUP_FINALLY, end); compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, FINALLY_TRY, body, end)) + if (!compiler_push_fblock(c, break_finally ? FINALLY_TRY2 : FINALLY_TRY, body, end)) return 0; if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) { if (!compiler_try_except(c, s)) @@ -2833,15 +2938,11 @@ compiler_try_finally(struct compiler *c, stmt_ty s) } ADDOP(c, POP_BLOCK); ADDOP(c, BEGIN_FINALLY); - compiler_pop_fblock(c, FINALLY_TRY, body); + compiler_pop_fblock(c, break_finally ? FINALLY_TRY2 : FINALLY_TRY, body); + + c->u->u_curblock->b_next = end; + c->u->u_curblock = newcurblock; - /* `finally` block */ - compiler_use_next_block(c, end); - if (!compiler_push_fblock(c, FINALLY_END, end, NULL)) - return 0; - VISIT_SEQ(c, stmt, s->v.Try.finalbody); - ADDOP(c, END_FINALLY); - compiler_pop_fblock(c, FINALLY_END, end); return 1; } @@ -4240,10 +4341,10 @@ compiler_sync_comprehension_generator(struct compiler *c, ADDOP_I(c, SET_ADD, gen_index + 1); break; case COMP_DICTCOMP: - /* With 'd[k] = v', v is evaluated before k, so we do + /* With '{k: v}', k is evaluated before v, so we do the same. */ - VISIT(c, expr, val); VISIT(c, expr, elt); + VISIT(c, expr, val); ADDOP_I(c, MAP_ADD, gen_index + 1); break; default: @@ -4329,10 +4430,10 @@ compiler_async_comprehension_generator(struct compiler *c, ADDOP_I(c, SET_ADD, gen_index + 1); break; case COMP_DICTCOMP: - /* With 'd[k] = v', v is evaluated before k, so we do + /* With '{k: v}', k is evaluated before v, so we do the same. */ - VISIT(c, expr, val); VISIT(c, expr, elt); + VISIT(c, expr, val); ADDOP_I(c, MAP_ADD, gen_index + 1); break; default: @@ -5815,13 +5916,11 @@ makecode(struct compiler *c, struct assembler *a) if (maxdepth < 0) { goto error; } - co = PyCode_New(posonlyargcount+posorkeywordargcount, posonlyargcount, - kwonlyargcount, nlocals_int, maxdepth, flags, - bytecode, consts, names, varnames, - freevars, cellvars, - c->c_filename, c->u->u_name, - c->u->u_firstlineno, - a->a_lnotab); + co = PyCode_NewWithPosOnlyArgs(posonlyargcount+posorkeywordargcount, + posonlyargcount, kwonlyargcount, nlocals_int, + maxdepth, flags, bytecode, consts, names, + varnames, freevars, cellvars, c->c_filename, + c->u->u_name, c->u->u_firstlineno, a->a_lnotab); error: Py_XDECREF(consts); Py_XDECREF(names); diff --git a/Python/condvar.h b/Python/condvar.h index f54adc5ea8e829..8cba19b84612dc 100644 --- a/Python/condvar.h +++ b/Python/condvar.h @@ -178,7 +178,7 @@ _PyCOND_WAIT_MS(PyCOND_T *cv, PyMUTEX_T *cs, DWORD ms) * just means an extra spurious wakeup for a waiting thread. * ('waiting' corresponds to the semaphore's "negative" count and * we may end up with e.g. (waiting == -1 && sem.count == 1). When - * a new thread comes along, it will pass right throuhgh, having + * a new thread comes along, it will pass right through, having * adjusted it to (waiting == 0 && sem.count == 0). */ diff --git a/Python/dynload_win.c b/Python/dynload_win.c index 457d47f5eed50a..6deba1134e2a4b 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -38,24 +38,6 @@ const char *_PyImport_DynLoadFiletab[] = { NULL }; -/* Case insensitive string compare, to avoid any dependencies on particular - C RTL implementations */ - -static int strcasecmp (const char *string1, const char *string2) -{ - int first, second; - - do { - first = tolower(*string1); - second = tolower(*string2); - string1++; - string2++; - } while (first && first == second); - - return (first - second); -} - - /* Function to return the name of the "python" DLL that the supplied module directly imports. Looks through the list of imported modules and returns the first entry that starts with "python" (case sensitive) and @@ -258,8 +240,8 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, This should not happen if called correctly. */ if (theLength == 0) { message = PyUnicode_FromFormat( - "DLL load failed with error code %u", - errorCode); + "DLL load failed with error code %u while importing %s", + errorCode, shortname); } else { /* For some reason a \r\n is appended to the text */ @@ -269,8 +251,8 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, theLength -= 2; theInfo[theLength] = '\0'; } - message = PyUnicode_FromString( - "DLL load failed: "); + message = PyUnicode_FromFormat( + "DLL load failed while importing %s: ", shortname); PyUnicode_AppendAndDel(&message, PyUnicode_FromWideChar( @@ -297,7 +279,7 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, import_python = GetPythonImport(hDLL); if (import_python && - strcasecmp(buffer,import_python)) { + _stricmp(buffer,import_python)) { PyErr_Format(PyExc_ImportError, "Module use of %.150s conflicts " "with this version of Python.", diff --git a/Python/fileutils.c b/Python/fileutils.c index 178e2f1268f831..e79e732d1f55b7 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -878,7 +878,12 @@ _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); result->st_nlink = info->nNumberOfLinks; result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow; - if (reparse_tag == IO_REPARSE_TAG_SYMLINK) { + /* bpo-37834: Only actual symlinks set the S_IFLNK flag. But lstat() will + open other name surrogate reparse points without traversing them. To + detect/handle these, check st_file_attributes and st_reparse_tag. */ + result->st_reparse_tag = reparse_tag; + if (info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && + reparse_tag == IO_REPARSE_TAG_SYMLINK) { /* first clear the S_IFMT bits */ result->st_mode ^= (result->st_mode & S_IFMT); /* now set the bits that make this a symlink */ @@ -1129,11 +1134,18 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) flags = HANDLE_FLAG_INHERIT; else flags = 0; - if (!SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) { + + /* This check can be removed once support for Windows 7 ends. */ +#define CONSOLE_PSEUDOHANDLE(handle) (((ULONG_PTR)(handle) & 0x3) == 0x3 && \ + GetFileType(handle) == FILE_TYPE_CHAR) + + if (!CONSOLE_PSEUDOHANDLE(handle) && + !SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) { if (raise) PyErr_SetFromWindowsErr(0); return -1; } +#undef CONSOLE_PSEUDOHANDLE return 0; #else @@ -1776,7 +1788,6 @@ _Py_dup(int fd) { #ifdef MS_WINDOWS HANDLE handle; - DWORD ftype; #endif assert(PyGILState_Check()); @@ -1790,9 +1801,6 @@ _Py_dup(int fd) return -1; } - /* get the file type, ignore the error if it failed */ - ftype = GetFileType(handle); - Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH fd = dup(fd); @@ -1803,14 +1811,11 @@ _Py_dup(int fd) return -1; } - /* Character files like console cannot be make non-inheritable */ - if (ftype != FILE_TYPE_CHAR) { - if (_Py_set_inheritable(fd, 0, NULL) < 0) { - _Py_BEGIN_SUPPRESS_IPH - close(fd); - _Py_END_SUPPRESS_IPH - return -1; - } + if (_Py_set_inheritable(fd, 0, NULL) < 0) { + _Py_BEGIN_SUPPRESS_IPH + close(fd); + _Py_END_SUPPRESS_IPH + return -1; } #elif defined(HAVE_FCNTL_H) && defined(F_DUPFD_CLOEXEC) Py_BEGIN_ALLOW_THREADS diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 3e9e9ba08602cd..7c4ecf0b3e2cb7 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -590,7 +590,7 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix, spec->n_remainder + spec->n_rpadding; } -/* Fill in the digit parts of a numbers's string representation, +/* Fill in the digit parts of a number's string representation, as determined in calc_number_widths(). Return -1 on error, or 0 on success. */ static int diff --git a/Python/frozenmain.c b/Python/frozenmain.c index c56938ab489948..7f9cc193173605 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -40,11 +40,7 @@ Py_FrozenMain(int argc, char **argv) } PyConfig config; - status = PyConfig_InitPythonConfig(&config); - if (PyStatus_Exception(status)) { - PyConfig_Clear(&config); - Py_ExitStatusException(status); - } + PyConfig_InitPythonConfig(&config); config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') diff --git a/Python/getargs.c b/Python/getargs.c index 59f0fdabb74a65..c1b7b1a275b009 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -610,24 +610,18 @@ convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags, -/* Format an error message generated by convertsimple(). */ +/* Format an error message generated by convertsimple(). + displayname must be UTF-8 encoded. +*/ void -_PyArg_BadArgument(const char *fname, int iarg, +_PyArg_BadArgument(const char *fname, const char *displayname, const char *expected, PyObject *arg) { - if (iarg) { - PyErr_Format(PyExc_TypeError, - "%.200s() argument %d must be %.50s, not %.50s", - fname, iarg, expected, - arg == Py_None ? "None" : arg->ob_type->tp_name); - } - else { - PyErr_Format(PyExc_TypeError, - "%.200s() argument must be %.50s, not %.50s", - fname, expected, - arg == Py_None ? "None" : arg->ob_type->tp_name); - } + PyErr_Format(PyExc_TypeError, + "%.200s() %.200s must be %.50s, not %.50s", + fname, displayname, expected, + arg == Py_None ? "None" : arg->ob_type->tp_name); } static const char * @@ -887,7 +881,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, case 'f': {/* float */ float *p = va_arg(*p_va, float *); double dval = PyFloat_AsDouble(arg); - if (PyErr_Occurred()) + if (dval == -1.0 && PyErr_Occurred()) RETURN_ERR_OCCURRED; else *p = (float) dval; @@ -897,7 +891,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, case 'd': {/* double */ double *p = va_arg(*p_va, double *); double dval = PyFloat_AsDouble(arg); - if (PyErr_Occurred()) + if (dval == -1.0 && PyErr_Occurred()) RETURN_ERR_OCCURRED; else *p = dval; @@ -1205,7 +1199,19 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, trailing 0-byte */ - FETCH_SIZE; + int *q = NULL; Py_ssize_t *q2 = NULL; + if (flags & FLAG_SIZE_T) { + q2 = va_arg(*p_va, Py_ssize_t*); + } + else { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) + { + Py_DECREF(s); + return NULL; + } + q = va_arg(*p_va, int*); + } format++; if (q == NULL && q2 == NULL) { @@ -1238,7 +1244,19 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } } memcpy(*buffer, ptr, size+1); - STORE_SIZE(size); + + if (flags & FLAG_SIZE_T) { + *q2 = size; + } + else { + if (INT_MAX < size) { + Py_DECREF(s); + PyErr_SetString(PyExc_OverflowError, + "size does not fit in an int"); + return converterr("", arg, msgbuf, bufsize); + } + *q = (int)size; + } } else { /* Using a 0-terminated buffer: diff --git a/Python/hamt.c b/Python/hamt.c index b3cbf9ac820879..38412596a37b02 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -6,7 +6,7 @@ #include "structmember.h" /* -This file provides an implemention of an immutable mapping using the +This file provides an implementation of an immutable mapping using the Hash Array Mapped Trie (or HAMT) datastructure. This design allows to have: diff --git a/Python/import.c b/Python/import.c index ab7db6bc17f6b1..495012d1c7da66 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1601,22 +1601,20 @@ resolve_name(PyObject *name, PyObject *globals, int level) if (dot == -2) { goto error; } - - if (dot >= 0) { - PyObject *substr = PyUnicode_Substring(package, 0, dot); - if (substr == NULL) { - goto error; - } - Py_SETREF(package, substr); + else if (dot == -1) { + goto no_parent_error; } + PyObject *substr = PyUnicode_Substring(package, 0, dot); + if (substr == NULL) { + goto error; + } + Py_SETREF(package, substr); } } last_dot = PyUnicode_GET_LENGTH(package); if (last_dot == 0) { - PyErr_SetString(PyExc_ImportError, - "attempted relative import with no known parent package"); - goto error; + goto no_parent_error; } for (level_up = 1; level_up < level; level_up += 1) { @@ -1642,6 +1640,11 @@ resolve_name(PyObject *name, PyObject *globals, int level) Py_DECREF(base); return abs_name; + no_parent_error: + PyErr_SetString(PyExc_ImportError, + "attempted relative import " + "with no known parent package"); + error: Py_XDECREF(package); return NULL; diff --git a/Python/importlib.h b/Python/importlib.h index 5bd1d179e2f0c8..67195747d8d90c 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -301,14 +301,14 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,115,6,0,0,0,8,2,8,4,8,4,114,50,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,2,124,0, - 25,0,131,0,125,1,87,0,110,24,4,0,116,3,107,10, + 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,4,100,1,107,8, - 114,76,116,5,124,0,131,1,125,1,110,8,116,6,124,0, + 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,7,160,8,124,1,124,2,161,2,116,2,124,0,60,0, - 87,0,53,0,116,0,160,9,161,0,1,0,88,0,124,1, + 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, @@ -320,22 +320,22 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 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,2,160,3,124,1, - 161,1,124,0,107,8,114,30,116,2,124,1,61,0,87,0, - 53,0,116,0,160,4,161,0,1,0,88,0,100,0,83,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,13,95,109,111, - 100,117,108,101,95,108,111,99,107,115,114,34,0,0,0,218, - 12,114,101,108,101,97,115,101,95,108,111,99,107,41,2,218, + 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, - 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,49,0, - 0,0,114,20,0,0,0,218,8,95,119,101,97,107,114,101, - 102,114,61,0,0,0,114,60,0,0,0,41,3,114,17,0, + 57,0,0,0,114,58,0,0,0,114,59,0,0,0,114,60, + 0,0,0,218,8,75,101,121,69,114,114,111,114,114,23,0, + 0,0,114,49,0,0,0,114,20,0,0,0,218,8,95,119, + 101,97,107,114,101,102,114,61,0,0,0,41,3,114,17,0, 0,0,114,24,0,0,0,114,62,0,0,0,114,10,0,0, 0,114,10,0,0,0,114,11,0,0,0,114,53,0,0,0, 157,0,0,0,115,28,0,0,0,0,6,8,1,2,1,2, @@ -670,1121 +670,1120 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 1,18,1,10,1,8,1,4,255,6,2,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,114,0,0,0,124,0, - 106,0,125,2,122,76,124,0,106,1,124,1,106,1,107,2, + 0,8,0,0,0,67,0,0,0,115,106,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,87,0, - 110,26,4,0,116,6,107,10,114,108,1,0,1,0,1,0, - 89,0,100,1,83,0,89,0,110,2,88,0,100,0,83,0, - 114,116,0,0,0,41,7,114,117,0,0,0,114,17,0,0, - 0,114,109,0,0,0,114,113,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,106,0,0,0,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,108,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,8,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,119,0,0,0,114, - 113,0,0,0,114,118,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,47,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,114,123,0,0,0,120,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,119,0,0,0,41,2,114,30,0,0,0,114,123,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,123,0,0,0,129,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,117,0,0,0,114,17,0,0,0,218,10,114,112,97, - 114,116,105,116,105,111,110,114,47,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,133,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,118,0,0,0,114,47,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,124,0,0,0,141,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,118,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,124,0, - 0,0,145,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,48,0,0,0,114,125,0, - 0,0,218,8,112,114,111,112,101,114,116,121,114,123,0,0, - 0,218,6,115,101,116,116,101,114,114,130,0,0,0,114,124, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,112,0,0,0,49,1,0,0, - 115,32,0,0,0,8,1,4,36,4,1,2,255,12,12,8, - 10,8,12,2,1,10,8,4,1,10,3,2,1,10,7,2, - 1,10,3,4,1,114,112,0,0,0,169,2,114,113,0,0, - 0,114,115,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,110,24, - 4,0,116,5,107,10,114,130,1,0,1,0,1,0,100,2, - 125,3,89,0,110,2,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,109,0,0,0,41,2,114, - 109,0,0,0,114,117,0,0,0,114,115,0,0,0,70,114, - 135,0,0,0,41,7,114,4,0,0,0,114,126,0,0,0, - 114,127,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,115, - 0,0,0,114,79,0,0,0,114,112,0,0,0,41,6,114, - 17,0,0,0,114,109,0,0,0,114,113,0,0,0,114,115, - 0,0,0,114,136,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,150,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,113,0,0,0,70,84,41,13,114,105,0,0,0,114, - 106,0,0,0,114,1,0,0,0,114,98,0,0,0,114,108, - 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,112,0,0,0,114,118,0, - 0,0,114,123,0,0,0,114,117,0,0,0,41,8,114,96, - 0,0,0,114,109,0,0,0,114,113,0,0,0,114,95,0, - 0,0,114,17,0,0,0,90,8,108,111,99,97,116,105,111, - 110,114,123,0,0,0,114,117,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,176,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,142, - 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,141,0,0,0,114, - 108,0,0,0,114,139,0,0,0,41,21,114,6,0,0,0, - 114,17,0,0,0,114,1,0,0,0,114,106,0,0,0,114, - 109,0,0,0,114,117,0,0,0,114,126,0,0,0,114,127, - 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,108,0,0,0,114,98,0,0,0,114, - 130,0,0,0,114,145,0,0,0,114,105,0,0,0,114,141, - 0,0,0,114,124,0,0,0,114,113,0,0,0,114,123,0, - 0,0,114,139,0,0,0,41,5,114,95,0,0,0,114,96, - 0,0,0,114,144,0,0,0,114,109,0,0,0,114,146,0, + 124,0,106,5,124,1,106,5,107,2,87,0,83,0,4,0, + 116,6,107,10,114,100,1,0,1,0,1,0,89,0,100,1, + 83,0,88,0,100,0,83,0,114,116,0,0,0,41,7,114, + 117,0,0,0,114,17,0,0,0,114,109,0,0,0,114,113, + 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,106,0,0,0,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,108,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,119,0,0,0,114,113,0,0,0,114,118,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,47,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,123,0,0, + 0,120,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,119,0,0,0,41,2,114, + 30,0,0,0,114,123,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,123,0,0,0,129,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,117,0,0,0,114,17, + 0,0,0,218,10,114,112,97,114,116,105,116,105,111,110,114, + 47,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,133,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,118,0,0,0,114,47,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,221,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,148, - 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,109,0,0,0,114, - 149,0,0,0,114,79,0,0,0,114,18,0,0,0,114,17, - 0,0,0,114,148,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,37,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,152,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,4,0,0,0,67,0,0,0,115,106, - 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, - 66,124,0,106,2,100,1,107,8,114,50,100,3,160,3,124, - 1,161,1,83,0,100,4,160,3,124,1,124,0,106,2,161, - 2,83,0,110,36,124,0,106,4,114,86,100,5,160,3,124, - 1,124,0,106,1,161,2,83,0,100,6,160,3,124,0,106, - 0,124,0,106,1,161,2,83,0,100,1,83,0,41,7,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,250,18,60,109, - 111,100,117,108,101,32,123,33,114,125,32,40,123,125,41,62, - 41,5,114,17,0,0,0,114,113,0,0,0,114,109,0,0, - 0,114,45,0,0,0,114,124,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,107,0,0,0,54,2,0,0,115, - 16,0,0,0,0,3,20,1,10,1,10,1,10,2,16,2, - 6,1,14,2,114,107,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,204,0,0,0,124,0,106,0,125,2,116,1,124, - 2,131,1,143,180,1,0,116,2,106,3,160,4,124,2,161, - 1,124,1,107,9,114,54,100,1,160,5,124,2,161,1,125, - 3,116,6,124,3,124,2,100,2,141,2,130,1,122,106,124, - 0,106,7,100,3,107,8,114,106,124,0,106,8,100,3,107, - 8,114,90,116,6,100,4,124,0,106,0,100,2,141,2,130, - 1,116,9,124,0,124,1,100,5,100,6,141,3,1,0,110, - 52,116,9,124,0,124,1,100,5,100,6,141,3,1,0,116, - 10,124,0,106,7,100,7,131,2,115,146,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,13,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,8,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,30,109, - 111,100,117,108,101,32,123,33,114,125,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,143,0,0,0,114,150,0,0,0,41,14, - 114,17,0,0,0,114,50,0,0,0,114,15,0,0,0,114, - 92,0,0,0,114,34,0,0,0,114,45,0,0,0,114,79, - 0,0,0,114,109,0,0,0,114,117,0,0,0,114,148,0, - 0,0,114,4,0,0,0,218,11,108,111,97,100,95,109,111, - 100,117,108,101,114,150,0,0,0,218,3,112,111,112,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,71,2,0,0,115,34,0,0, - 0,0,2,6,1,10,1,16,1,10,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,145,0,0,0,114,141,0, - 0,0,114,128,0,0,0,114,22,0,0,0,114,105,0,0, - 0,41,14,114,109,0,0,0,114,155,0,0,0,114,17,0, - 0,0,114,15,0,0,0,114,92,0,0,0,114,156,0,0, - 0,114,6,0,0,0,114,98,0,0,0,114,106,0,0,0, - 114,1,0,0,0,114,145,0,0,0,114,4,0,0,0,114, - 129,0,0,0,114,105,0,0,0,114,151,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,101,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,158,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,3,124,0, - 106,7,100,4,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,5,124,0,106,7,124,0, - 106,0,131,3,1,0,87,0,53,0,100,6,124,0,95,4, - 88,0,124,1,83,0,41,7,78,114,150,0,0,0,84,114, - 154,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,70,41,14, - 114,109,0,0,0,114,4,0,0,0,114,158,0,0,0,114, - 152,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,117,0,0,0,114,79,0,0,0,114,150,0,0, - 0,114,63,0,0,0,114,156,0,0,0,114,76,0,0,0, - 114,151,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,138,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,159,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,50, - 0,0,0,114,17,0,0,0,114,159,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,180,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,136,0,0,0,101,0,90,1,100,0,90,2, - 100,1,90,3,101,4,100,2,100,3,132,0,131,1,90,5, - 101,6,100,19,100,5,100,6,132,1,131,1,90,7,101,6, - 100,20,100,7,100,8,132,1,131,1,90,8,101,6,100,9, - 100,10,132,0,131,1,90,9,101,6,100,11,100,12,132,0, - 131,1,90,10,101,6,101,11,100,13,100,14,132,0,131,1, - 131,1,90,12,101,6,101,11,100,15,100,16,132,0,131,1, - 131,1,90,13,101,6,101,11,100,17,100,18,132,0,131,1, - 131,1,90,14,101,6,101,15,131,1,90,16,100,4,83,0, - 41,21,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,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,12, - 0,0,0,100,1,160,0,124,0,106,1,161,1,83,0,41, - 2,250,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,122,24,60,109,111,100,117,108,101,32, - 123,33,114,125,32,40,98,117,105,108,116,45,105,110,41,62, - 41,2,114,45,0,0,0,114,1,0,0,0,41,1,114,96, + 0,114,124,0,0,0,141,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,118,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,124,0,0,0,145,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,48,0,0,0,114,125,0,0,0,218,8,112,114,111,112, + 101,114,116,121,114,123,0,0,0,218,6,115,101,116,116,101, + 114,114,130,0,0,0,114,124,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 112,0,0,0,49,1,0,0,115,32,0,0,0,8,1,4, + 36,4,1,2,255,12,12,8,10,8,12,2,1,10,8,4, + 1,10,3,2,1,10,7,2,1,10,3,4,1,114,112,0, + 0,0,169,2,114,113,0,0,0,114,115,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,109,0,0,0,41,2,114,109,0,0,0,114,117,0,0, + 0,114,115,0,0,0,70,114,135,0,0,0,41,7,114,4, + 0,0,0,114,126,0,0,0,114,127,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,115,0,0,0,114,79,0,0,0, + 114,112,0,0,0,41,6,114,17,0,0,0,114,109,0,0, + 0,114,113,0,0,0,114,115,0,0,0,114,136,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,150,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,113,0,0,0,70,84, + 41,13,114,105,0,0,0,114,106,0,0,0,114,1,0,0, + 0,114,98,0,0,0,114,108,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,112,0,0,0,114,118,0,0,0,114,123,0,0,0,114, + 117,0,0,0,41,8,114,96,0,0,0,114,109,0,0,0, + 114,113,0,0,0,114,95,0,0,0,114,17,0,0,0,90, + 8,108,111,99,97,116,105,111,110,114,123,0,0,0,114,117, 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,99,0,0,0,204,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,44,0,0,0,124,2, - 100,0,107,9,114,12,100,0,83,0,116,0,160,1,124,1, - 161,1,114,36,116,2,124,1,124,0,100,1,100,2,141,3, - 83,0,100,0,83,0,100,0,83,0,41,3,78,122,8,98, - 117,105,108,116,45,105,110,114,137,0,0,0,41,3,114,57, - 0,0,0,90,10,105,115,95,98,117,105,108,116,105,110,114, - 91,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,213,2,0,0,115,10,0,0, - 0,0,2,8,1,4,1,10,1,14,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,166,0,0,0,114,109,0, - 0,0,41,4,114,163,0,0,0,114,81,0,0,0,114,164, - 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,222,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,100,1,160,4,124,1, - 106,0,161,1,124,1,106,0,100,2,141,2,130,1,116,5, - 116,6,106,7,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,8,114,17,0,0,0,114,15,0,0,0,114,78,0,0, - 0,114,79,0,0,0,114,45,0,0,0,114,67,0,0,0, - 114,57,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,149,0,0,0,234,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, + 0,0,218,17,95,115,112,101,99,95,102,114,111,109,95,109, + 111,100,117,108,101,176,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,142,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,141,0,0,0,114,108,0,0,0,114,139,0,0, + 0,41,21,114,6,0,0,0,114,17,0,0,0,114,1,0, + 0,0,114,106,0,0,0,114,109,0,0,0,114,117,0,0, + 0,114,126,0,0,0,114,127,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,108,0, + 0,0,114,98,0,0,0,114,130,0,0,0,114,145,0,0, + 0,114,105,0,0,0,114,141,0,0,0,114,124,0,0,0, + 114,113,0,0,0,114,123,0,0,0,114,139,0,0,0,41, + 5,114,95,0,0,0,114,96,0,0,0,114,144,0,0,0, + 114,109,0,0,0,114,146,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,221,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,148,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,109,0,0,0,114,149,0,0,0,114,79,0,0, + 0,114,18,0,0,0,114,17,0,0,0,114,148,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,37,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,152,0,0,0,99,1,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,0, + 0,0,67,0,0,0,115,106,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,66,124,0,106,2,100,1,107, + 8,114,50,100,3,160,3,124,1,161,1,83,0,100,4,160, + 3,124,1,124,0,106,2,161,2,83,0,110,36,124,0,106, + 4,114,86,100,5,160,3,124,1,124,0,106,1,161,2,83, + 0,100,6,160,3,124,0,106,0,124,0,106,1,161,2,83, + 0,100,1,83,0,41,7,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,250,18,60,109,111,100,117,108,101,32,123,33, + 114,125,32,40,123,125,41,62,41,5,114,17,0,0,0,114, + 113,0,0,0,114,109,0,0,0,114,45,0,0,0,114,124, + 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,107, + 0,0,0,54,2,0,0,115,16,0,0,0,0,3,20,1, + 10,1,10,1,10,2,16,2,6,1,14,2,114,107,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,204,0,0,0,124, + 0,106,0,125,2,116,1,124,2,131,1,143,180,1,0,116, + 2,106,3,160,4,124,2,161,1,124,1,107,9,114,54,100, + 1,160,5,124,2,161,1,125,3,116,6,124,3,124,2,100, + 2,141,2,130,1,122,106,124,0,106,8,100,3,107,8,114, + 106,124,0,106,9,100,3,107,8,114,90,116,6,100,4,124, + 0,106,0,100,2,141,2,130,1,116,10,124,0,124,1,100, + 5,100,6,141,3,1,0,110,52,116,10,124,0,124,1,100, + 5,100,6,141,3,1,0,116,11,124,0,106,8,100,7,131, + 2,115,146,124,0,106,8,160,12,124,2,161,1,1,0,110, + 12,124,0,106,8,160,13,124,1,161,1,1,0,87,0,53, + 0,116,2,106,3,160,7,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,8,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,30,109,111,100,117,108,101,32,123,33, + 114,125,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,143,0,0, + 0,114,150,0,0,0,41,14,114,17,0,0,0,114,50,0, + 0,0,114,15,0,0,0,114,92,0,0,0,114,34,0,0, + 0,114,45,0,0,0,114,79,0,0,0,218,3,112,111,112, + 114,109,0,0,0,114,117,0,0,0,114,148,0,0,0,114, + 4,0,0,0,218,11,108,111,97,100,95,109,111,100,117,108, + 101,114,150,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, + 71,2,0,0,115,34,0,0,0,0,2,6,1,10,1,16, + 1,10,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,145,0,0,0,114,141,0,0,0,114,128,0,0,0,114, + 22,0,0,0,114,105,0,0,0,41,14,114,109,0,0,0, + 114,156,0,0,0,114,17,0,0,0,114,15,0,0,0,114, + 92,0,0,0,114,155,0,0,0,114,6,0,0,0,114,98, + 0,0,0,114,106,0,0,0,114,1,0,0,0,114,145,0, + 0,0,114,4,0,0,0,114,129,0,0,0,114,105,0,0, + 0,114,151,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, + 101,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, + 158,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,150,0,0,0,84,70,114,154,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,109,0,0,0,114,4,0, + 0,0,114,158,0,0,0,114,152,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,117,0,0,0,114, + 79,0,0,0,114,150,0,0,0,114,63,0,0,0,114,155, + 0,0,0,114,76,0,0,0,114,151,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,138,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,159,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,50,0,0,0,114,17,0,0,0, + 114,159,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, + 180,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,136,0,0,0, + 101,0,90,1,100,0,90,2,100,1,90,3,101,4,100,2, + 100,3,132,0,131,1,90,5,101,6,100,19,100,5,100,6, + 132,1,131,1,90,7,101,6,100,20,100,7,100,8,132,1, + 131,1,90,8,101,6,100,9,100,10,132,0,131,1,90,9, + 101,6,100,11,100,12,132,0,131,1,90,10,101,6,101,11, + 100,13,100,14,132,0,131,1,131,1,90,12,101,6,101,11, + 100,15,100,16,132,0,131,1,131,1,90,13,101,6,101,11, + 100,17,100,18,132,0,131,1,131,1,90,14,101,6,101,15, + 131,1,90,16,100,4,83,0,41,21,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,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,12,0,0,0,100,1,160,0,124, + 0,106,1,161,1,83,0,41,2,250,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,122,24, + 60,109,111,100,117,108,101,32,123,33,114,125,32,40,98,117, + 105,108,116,45,105,110,41,62,41,2,114,45,0,0,0,114, + 1,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,204, + 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,44,0,0,0,124,2,100,0,107,9,114,12,100,0, + 83,0,116,0,160,1,124,1,161,1,114,36,116,2,124,1, + 124,0,100,1,100,2,141,3,83,0,100,0,83,0,100,0, + 83,0,41,3,78,122,8,98,117,105,108,116,45,105,110,114, + 137,0,0,0,41,3,114,57,0,0,0,90,10,105,115,95, + 98,117,105,108,116,105,110,114,91,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, + 213,2,0,0,115,10,0,0,0,0,2,8,1,4,1,10, + 1,14,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,166,0,0,0,114,109,0,0,0,41,4,114,163,0,0, + 0,114,81,0,0,0,114,164,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,222,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,100,1,160,4,124,1,106,0,161,1,124,1,106,0, + 100,2,141,2,130,1,116,5,116,6,106,7,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,8,114,17,0,0,0,114, + 15,0,0,0,114,78,0,0,0,114,79,0,0,0,114,45, + 0,0,0,114,67,0,0,0,114,57,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,149,0,0,0,234,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,67,0,0,0,114, + 57,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,150,0, + 0,0,242,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,163,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,247,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,168,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,253,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,168,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,115,0,0,0,3,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,17,114,1,0, + 0,0,114,0,0,0,0,114,2,0,0,0,114,3,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,166,0,0,0,114,167,0,0,0,114,149,0,0,0, + 114,150,0,0,0,114,86,0,0,0,114,169,0,0,0,114, + 170,0,0,0,114,115,0,0,0,114,97,0,0,0,114,156, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,160,0,0,0,195,2,0,0, + 115,42,0,0,0,8,2,4,7,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, + 160,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,4,0,0, + 0,67,0,0,0,115,16,0,0,0,100,1,160,0,124,0, + 106,1,116,2,106,3,161,2,83,0,41,2,114,161,0,0, + 0,114,153,0,0,0,41,4,114,45,0,0,0,114,1,0, + 0,0,114,173,0,0,0,114,138,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,23,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,41,2,78, + 114,137,0,0,0,41,4,114,57,0,0,0,114,88,0,0, + 0,114,91,0,0,0,114,138,0,0,0,114,162,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 166,0,0,0,32,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,57,0,0,0,114,88,0,0,0,41,3,114,163,0, + 0,0,114,81,0,0,0,114,164,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,167,0,0,0, + 39,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, + 163,0,0,0,114,95,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,149,0,0,0,48,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,100,1,160,5,124,1,161,1, + 124,1,100,2,141,2,130,1,116,6,116,2,106,7,124,1, + 131,2,125,2,116,8,124,2,124,0,106,9,131,2,1,0, + 100,0,83,0,114,87,0,0,0,41,10,114,105,0,0,0, + 114,17,0,0,0,114,57,0,0,0,114,88,0,0,0,114, + 79,0,0,0,114,45,0,0,0,114,67,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,150,0, + 0,0,52,3,0,0,115,14,0,0,0,0,2,8,1,10, + 1,10,1,2,255,6,2,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,168,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,156,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,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,67,0,0,0,114,57,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,150,0,0,0,242,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,163,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,247,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,168,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,253,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,168,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,57,0,0,0,114,175,0,0,0,114,168,0,0, 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,115,0,0,0,3,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,17,114,1,0,0,0,114,0,0,0,0,114, - 2,0,0,0,114,3,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,166,0,0,0,114,167, - 0,0,0,114,149,0,0,0,114,150,0,0,0,114,86,0, - 0,0,114,169,0,0,0,114,170,0,0,0,114,115,0,0, - 0,114,97,0,0,0,114,155,0,0,0,114,10,0,0,0, + 114,169,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,168,0,0,0, 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 160,0,0,0,195,2,0,0,115,42,0,0,0,8,2,4, - 7,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,160,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,4,0,0,0,67,0,0,0,115,16,0, - 0,0,100,1,160,0,124,0,106,1,116,2,106,3,161,2, - 83,0,41,2,114,161,0,0,0,114,153,0,0,0,41,4, - 114,45,0,0,0,114,1,0,0,0,114,173,0,0,0,114, - 138,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,23,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,41,2,78,114,137,0,0,0,41,4,114, - 57,0,0,0,114,88,0,0,0,114,91,0,0,0,114,138, - 0,0,0,114,162,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,166,0,0,0,32,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,57,0,0,0,114,88, - 0,0,0,41,3,114,163,0,0,0,114,81,0,0,0,114, - 164,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,167,0,0,0,39,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,163,0,0,0,114,95,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,149,0,0,0,48,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, - 100,1,160,5,124,1,161,1,124,1,100,2,141,2,130,1, - 116,6,116,2,106,7,124,1,131,2,125,2,116,8,124,2, - 124,0,106,9,131,2,1,0,100,0,83,0,114,87,0,0, - 0,41,10,114,105,0,0,0,114,17,0,0,0,114,57,0, - 0,0,114,88,0,0,0,114,79,0,0,0,114,45,0,0, - 0,114,67,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,150,0,0,0,52,3,0,0,115,14, - 0,0,0,0,2,8,1,10,1,10,1,2,255,6,2,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, - 168,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,155,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,57,0,0,0,114, - 175,0,0,0,114,168,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,169,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,168,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,170,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,57, - 0,0,0,90,17,105,115,95,102,114,111,122,101,110,95,112, - 97,99,107,97,103,101,114,168,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,115,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,138,0,0,0,114,171,0,0,0,114,99,0,0, - 0,114,172,0,0,0,114,166,0,0,0,114,167,0,0,0, - 114,149,0,0,0,114,150,0,0,0,114,155,0,0,0,114, - 90,0,0,0,114,169,0,0,0,114,170,0,0,0,114,115, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,173,0,0,0,12,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,8,2, - 1,10,8,2,1,2,1,12,4,2,1,2,1,12,4,2, - 1,2,1,114,173,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,57,0,0,0, - 114,58,0,0,0,114,47,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,54,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,57,0,0,0,114,60,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,56,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,54,0,0, - 0,114,56,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,178,0,0,0,91, - 3,0,0,115,6,0,0,0,8,2,4,2,8,4,114,178, - 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,64,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, - 60,100,5,160,3,124,4,124,0,161,2,83,0,124,4,83, - 0,41,6,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,128,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,250,5,123,125,46,123, - 125,41,4,218,6,114,115,112,108,105,116,218,3,108,101,110, - 218,10,86,97,108,117,101,69,114,114,111,114,114,45,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,188,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,167,0,0,0,114,91,0,0,0,41,4,218,6,102, - 105,110,100,101,114,114,17,0,0,0,114,164,0,0,0,114, - 109,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,190,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,178,0,0,0, - 114,166,0,0,0,114,106,0,0,0,114,190,0,0,0,114, - 105,0,0,0,41,10,114,17,0,0,0,114,164,0,0,0, - 114,165,0,0,0,114,191,0,0,0,90,9,105,115,95,114, - 101,108,111,97,100,114,189,0,0,0,114,166,0,0,0,114, - 95,0,0,0,114,96,0,0,0,114,105,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,195,0,0,0,99,3,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,5,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,160,3,116,4,124,0,131, - 1,161,1,131,1,130,1,124,2,100,2,107,0,114,44,116, - 5,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,6,100,5,131,1,130,1,124, - 0,115,104,124,2,100,2,107,2,114,104,116,5,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,31,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,123,125,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,7, - 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,45,0,0, - 0,114,14,0,0,0,114,185,0,0,0,114,79,0,0,0, - 169,3,114,17,0,0,0,114,186,0,0,0,114,187,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,200, - 0,0,0,122,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,220,0,0,0,100,0,125,2,124,0,160, - 0,100,1,161,1,100,2,25,0,125,3,124,3,114,134,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,50,4,0,116, - 5,107,10,114,132,1,0,1,0,1,0,116,6,100,3,23, - 0,160,7,124,0,124,3,161,2,125,5,116,8,124,5,124, - 0,100,4,141,2,100,0,130,2,89,0,110,2,88,0,116, - 9,124,0,124,2,131,2,125,6,124,6,100,0,107,8,114, - 172,116,8,116,6,160,7,124,0,161,1,124,0,100,4,141, - 2,130,1,110,8,116,10,124,6,131,1,125,7,124,3,114, - 216,116,1,106,2,124,3,25,0,125,4,116,11,124,4,124, - 0,160,0,100,1,161,1,100,5,25,0,124,7,131,3,1, - 0,124,7,83,0,41,6,78,114,128,0,0,0,114,22,0, - 0,0,122,23,59,32,123,33,114,125,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,12,114,129,0,0,0,114,15,0,0, - 0,114,92,0,0,0,114,67,0,0,0,114,141,0,0,0, - 114,106,0,0,0,218,8,95,69,82,82,95,77,83,71,114, - 45,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,195,0,0,0,114,159, - 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,164,0,0,0,114,130,0, - 0,0,90,13,112,97,114,101,110,116,95,109,111,100,117,108, - 101,114,157,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,16,1,20,1,10,1,8, - 1,20,2,8,1,4,2,10,1,22,1,114,205,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,106,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,94,100,2,160,6,124,0,161,1,125,3, - 116,7,124,3,124,0,100,3,141,2,130,1,116,8,124,0, - 131,1,1,0,124,2,83,0,41,4,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,40,105,109,112,111,114,116,32,111, - 102,32,123,125,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,9,114,50,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,205,0,0,0, - 114,45,0,0,0,114,203,0,0,0,114,65,0,0,0,41, - 4,114,17,0,0,0,114,204,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,22,0,0,0,0,2,10, - 1,14,1,8,1,32,2,8,1,4,1,2,255,4,2,12, - 2,8,1,114,207,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,200,0,0,0,114,188,0,0,0,114, - 207,0,0,0,218,11,95,103,99,100,95,105,109,112,111,114, - 116,114,199,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,208,0,0,0,234,3,0,0,115,8, - 0,0,0,0,9,12,1,8,1,12,1,114,208,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,226,0,0,0,124,1,68,0,93, - 216,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,110,154,124,4,100, - 5,107,2,114,108,124,3,115,106,116,5,124,0,100,6,131, - 2,114,106,116,6,124,0,124,0,106,7,124,2,100,7,100, - 8,141,4,1,0,110,112,116,5,124,0,124,4,131,2,115, - 220,100,9,160,8,124,0,106,2,124,4,161,2,125,6,122, - 14,116,9,124,2,124,6,131,2,1,0,87,0,110,72,4, - 0,116,10,107,10,114,218,1,0,125,7,1,0,122,42,124, - 7,106,11,124,6,107,2,114,200,116,12,106,13,160,14,124, - 6,116,15,161,2,100,10,107,9,114,200,87,0,89,0,162, - 8,113,4,130,0,87,0,53,0,100,10,125,7,126,7,88, - 0,89,0,110,2,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,209,0,0,0,114,182,0,0,0,78,41,16, - 114,196,0,0,0,114,197,0,0,0,114,1,0,0,0,114, - 198,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,212,0,0,0,114,45,0,0,0,114,67,0,0,0,114, - 203,0,0,0,114,17,0,0,0,114,15,0,0,0,114,92, - 0,0,0,114,34,0,0,0,114,206,0,0,0,41,8,114, - 96,0,0,0,218,8,102,114,111,109,108,105,115,116,114,204, - 0,0,0,114,210,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,213,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,14,1,2,1,14,1,16, - 4,10,1,16,255,2,2,8,1,22,1,114,213,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,145,0,0,0, - 114,105,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,250,1, - 41,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,141,0,0,0,114,128,0,0,0,114,22, - 0,0,0,41,6,114,34,0,0,0,114,130,0,0,0,114, - 192,0,0,0,114,193,0,0,0,114,194,0,0,0,114,129, - 0,0,0,41,3,218,7,103,108,111,98,97,108,115,114,186, - 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,219,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,128,0,0,0,114,141, - 0,0,0,41,9,114,208,0,0,0,114,219,0,0,0,218, - 9,112,97,114,116,105,116,105,111,110,114,184,0,0,0,114, - 15,0,0,0,114,92,0,0,0,114,1,0,0,0,114,4, - 0,0,0,114,213,0,0,0,41,9,114,17,0,0,0,114, - 218,0,0,0,218,6,108,111,99,97,108,115,114,214,0,0, - 0,114,187,0,0,0,114,96,0,0,0,90,8,103,108,111, - 98,97,108,115,95,114,186,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,222,0,0,0,99,1,0,0,0,0, + 170,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,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,160, - 0,0,0,114,166,0,0,0,114,79,0,0,0,114,159,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,223,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,192,0,0,0,114,64,0,0,0,78,41,15,114,57,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,196,0,0,0,114,78,0, - 0,0,114,160,0,0,0,114,88,0,0,0,114,173,0,0, - 0,114,142,0,0,0,114,148,0,0,0,114,1,0,0,0, - 114,223,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,109,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,227,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,227,0,0,0,114,15,0,0,0,114, - 191,0,0,0,114,120,0,0,0,114,160,0,0,0,114,173, - 0,0,0,41,2,114,225,0,0,0,114,226,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,228,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,126,0,0,0, - 114,228,0,0,0,114,15,0,0,0,114,92,0,0,0,114, - 1,0,0,0,41,1,114,229,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,230,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, - 126,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,49,0,0,0,114,50,0,0, - 0,114,53,0,0,0,114,65,0,0,0,114,67,0,0,0, - 114,76,0,0,0,114,86,0,0,0,114,90,0,0,0,114, - 97,0,0,0,114,111,0,0,0,114,112,0,0,0,114,91, - 0,0,0,114,142,0,0,0,114,148,0,0,0,114,152,0, - 0,0,114,107,0,0,0,114,93,0,0,0,114,158,0,0, - 0,114,159,0,0,0,114,94,0,0,0,114,160,0,0,0, - 114,173,0,0,0,114,178,0,0,0,114,188,0,0,0,114, - 190,0,0,0,114,195,0,0,0,114,200,0,0,0,90,15, - 95,69,82,82,95,77,83,71,95,80,82,69,70,73,88,114, - 202,0,0,0,114,205,0,0,0,218,6,111,98,106,101,99, - 116,114,206,0,0,0,114,207,0,0,0,114,208,0,0,0, - 114,213,0,0,0,114,219,0,0,0,114,222,0,0,0,114, - 223,0,0,0,114,227,0,0,0,114,228,0,0,0,114,230, - 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,101, - 16,26,10,45,14,72,8,17,8,17,8,30,8,37,8,42, - 8,15,14,73,14,79,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, + 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,57,0,0,0,90,17,105,115,95, + 102,114,111,122,101,110,95,112,97,99,107,97,103,101,114,168, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,115,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,138,0,0,0,114, + 171,0,0,0,114,99,0,0,0,114,172,0,0,0,114,166, + 0,0,0,114,167,0,0,0,114,149,0,0,0,114,150,0, + 0,0,114,156,0,0,0,114,90,0,0,0,114,169,0,0, + 0,114,170,0,0,0,114,115,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 173,0,0,0,12,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,8,2,1,10,8,2,1,2,1,12, + 4,2,1,2,1,12,4,2,1,2,1,114,173,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,57,0,0,0,114,58,0,0,0,114,47,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,54,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,57,0,0, + 0,114,59,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,56,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,54,0,0,0,114,56,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,178,0,0,0,91,3,0,0,115,6,0,0,0, + 8,2,4,2,8,4,114,178,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,64,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,60,100,5,160,3,124,4,124, + 0,161,2,83,0,124,4,83,0,41,6,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, + 128,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,250,5,123,125,46,123,125,41,4,218,6,114,115,112, + 108,105,116,218,3,108,101,110,218,10,86,97,108,117,101,69, + 114,114,111,114,114,45,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,188,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,167,0,0,0,114,91, + 0,0,0,41,4,218,6,102,105,110,100,101,114,114,17,0, + 0,0,114,164,0,0,0,114,109,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, + 190,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,178,0,0,0,114,166,0,0,0,114,106,0, + 0,0,114,190,0,0,0,114,105,0,0,0,41,10,114,17, + 0,0,0,114,164,0,0,0,114,165,0,0,0,114,191,0, + 0,0,90,9,105,115,95,114,101,108,111,97,100,114,189,0, + 0,0,114,166,0,0,0,114,95,0,0,0,114,96,0,0, + 0,114,105,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,195,0,0,0,99,3,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,5,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,160,3,116,4,124,0,131,1,161,1,131,1,130,1,124, + 2,100,2,107,0,114,44,116,5,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, + 6,100,5,131,1,130,1,124,0,115,104,124,2,100,2,107, + 2,114,104,116,5,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, + 31,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,123,125, + 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,7,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,45,0,0,0,114,14,0,0,0,114,185, + 0,0,0,114,79,0,0,0,169,3,114,17,0,0,0,114, + 186,0,0,0,114,187,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,200,0,0,0,122,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,220,0,0, + 0,100,0,125,2,124,0,160,0,100,1,161,1,100,2,25, + 0,125,3,124,3,114,134,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,50,4,0,116,5,107,10,114,132,1,0,1, + 0,1,0,116,6,100,3,23,0,160,7,124,0,124,3,161, + 2,125,5,116,8,124,5,124,0,100,4,141,2,100,0,130, + 2,89,0,110,2,88,0,116,9,124,0,124,2,131,2,125, + 6,124,6,100,0,107,8,114,172,116,8,116,6,160,7,124, + 0,161,1,124,0,100,4,141,2,130,1,110,8,116,10,124, + 6,131,1,125,7,124,3,114,216,116,1,106,2,124,3,25, + 0,125,4,116,11,124,4,124,0,160,0,100,1,161,1,100, + 5,25,0,124,7,131,3,1,0,124,7,83,0,41,6,78, + 114,128,0,0,0,114,22,0,0,0,122,23,59,32,123,33, + 114,125,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,12,114, + 129,0,0,0,114,15,0,0,0,114,92,0,0,0,114,67, + 0,0,0,114,141,0,0,0,114,106,0,0,0,218,8,95, + 69,82,82,95,77,83,71,114,45,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,195,0,0,0,114,159,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,164,0,0,0,114,130,0,0,0,90,13,112,97,114,101, + 110,116,95,109,111,100,117,108,101,114,157,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,16,1,20,1,10,1,8,1,20,2,8,1,4,2,10, + 1,22,1,114,205,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,106,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,94,100,2, + 160,6,124,0,161,1,125,3,116,7,124,3,124,0,100,3, + 141,2,130,1,116,8,124,0,131,1,1,0,124,2,83,0, + 41,4,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,40, + 105,109,112,111,114,116,32,111,102,32,123,125,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,9,114, + 50,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,205,0,0,0,114,45,0,0,0,114,203,0, + 0,0,114,65,0,0,0,41,4,114,17,0,0,0,114,204, + 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,22,0,0,0,0,2,10,1,14,1,8,1,32,2,8, + 1,4,1,2,255,4,2,12,2,8,1,114,207,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,200,0, + 0,0,114,188,0,0,0,114,207,0,0,0,218,11,95,103, + 99,100,95,105,109,112,111,114,116,114,199,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,208,0, + 0,0,234,3,0,0,115,8,0,0,0,0,9,12,1,8, + 1,12,1,114,208,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,226, + 0,0,0,124,1,68,0,93,216,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, + 220,116,5,124,0,100,6,131,2,114,220,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,100,9,160,8,124,0,106, + 2,124,4,161,2,125,6,122,14,116,9,124,2,124,6,131, + 2,1,0,87,0,113,4,4,0,116,10,107,10,114,218,1, + 0,125,7,1,0,122,42,124,7,106,11,124,6,107,2,114, + 200,116,12,106,13,160,14,124,6,116,15,161,2,100,10,107, + 9,114,200,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,209,0,0,0, + 114,182,0,0,0,78,41,16,114,196,0,0,0,114,197,0, + 0,0,114,1,0,0,0,114,198,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,212,0,0,0,114,45,0, + 0,0,114,67,0,0,0,114,203,0,0,0,114,17,0,0, + 0,114,15,0,0,0,114,92,0,0,0,114,34,0,0,0, + 114,206,0,0,0,41,8,114,96,0,0,0,218,8,102,114, + 111,109,108,105,115,116,114,204,0,0,0,114,210,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,213,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,14,1,2,1,14,1,16,4,10,1,16,255,2,2,8, + 1,22,1,114,213,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,145,0,0,0,114,105,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,250,1,41,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,141,0,0, + 0,114,128,0,0,0,114,22,0,0,0,41,6,114,34,0, + 0,0,114,130,0,0,0,114,192,0,0,0,114,193,0,0, + 0,114,194,0,0,0,114,129,0,0,0,41,3,218,7,103, + 108,111,98,97,108,115,114,186,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,219,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,128,0,0,0,114,141,0,0,0,41,9,114,208,0, + 0,0,114,219,0,0,0,218,9,112,97,114,116,105,116,105, + 111,110,114,184,0,0,0,114,15,0,0,0,114,92,0,0, + 0,114,1,0,0,0,114,4,0,0,0,114,213,0,0,0, + 41,9,114,17,0,0,0,114,218,0,0,0,218,6,108,111, + 99,97,108,115,114,214,0,0,0,114,187,0,0,0,114,96, + 0,0,0,90,8,103,108,111,98,97,108,115,95,114,186,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,222,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,160,0,0,0,114,166,0,0,0, + 114,79,0,0,0,114,159,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,223,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,192,0,0,0,114,64,0, + 0,0,78,41,15,114,57,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,196,0,0,0,114,78,0,0,0,114,160,0,0,0,114, + 88,0,0,0,114,173,0,0,0,114,142,0,0,0,114,148, + 0,0,0,114,1,0,0,0,114,223,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,109,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,227,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,227,0, + 0,0,114,15,0,0,0,114,191,0,0,0,114,120,0,0, + 0,114,160,0,0,0,114,173,0,0,0,41,2,114,225,0, + 0,0,114,226,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, + 228,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,126,0,0,0,114,228,0,0,0,114,15,0, + 0,0,114,92,0,0,0,114,1,0,0,0,41,1,114,229, + 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,230, + 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,126,0,0,0,114,12,0,0, + 0,114,18,0,0,0,114,60,0,0,0,114,33,0,0,0, + 114,42,0,0,0,114,19,0,0,0,114,20,0,0,0,114, + 49,0,0,0,114,50,0,0,0,114,53,0,0,0,114,65, + 0,0,0,114,67,0,0,0,114,76,0,0,0,114,86,0, + 0,0,114,90,0,0,0,114,97,0,0,0,114,111,0,0, + 0,114,112,0,0,0,114,91,0,0,0,114,142,0,0,0, + 114,148,0,0,0,114,152,0,0,0,114,107,0,0,0,114, + 93,0,0,0,114,158,0,0,0,114,159,0,0,0,114,94, + 0,0,0,114,160,0,0,0,114,173,0,0,0,114,178,0, + 0,0,114,188,0,0,0,114,190,0,0,0,114,195,0,0, + 0,114,200,0,0,0,90,15,95,69,82,82,95,77,83,71, + 95,80,82,69,70,73,88,114,202,0,0,0,114,205,0,0, + 0,218,6,111,98,106,101,99,116,114,206,0,0,0,114,207, + 0,0,0,114,208,0,0,0,114,213,0,0,0,114,219,0, + 0,0,114,222,0,0,0,114,223,0,0,0,114,227,0,0, + 0,114,228,0,0,0,114,230,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,101,16,26,10,45,14,72,8,17, + 8,17,8,30,8,37,8,42,8,15,14,73,14,79,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/importlib_external.h b/Python/importlib_external.h index e724560d67a1c2..74d98bdebab5ea 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -1,1019 +1,1017 @@ /* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__importlib_bootstrap_external[] = { 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,5,0,0,0,64,0,0,0,115,52,2,0,0,100,0, + 0,5,0,0,0,64,0,0,0,115,32,2,0,0,100,0, 90,0,100,1,90,1,100,2,90,2,101,2,101,1,23,0, 90,3,100,3,100,4,132,0,90,4,100,5,100,6,132,0, 90,5,100,7,100,8,132,0,90,6,100,9,100,10,132,0, 90,7,100,11,100,12,132,0,90,8,100,13,100,14,132,0, 90,9,100,15,100,16,132,0,90,10,100,17,100,18,132,0, 90,11,100,19,100,20,132,0,90,12,100,21,100,22,132,0, - 90,13,100,23,100,24,132,0,90,14,100,25,102,1,100,26, - 100,27,132,1,90,15,101,16,101,15,106,17,131,1,90,18, - 100,28,160,19,100,29,100,30,161,2,100,31,23,0,90,20, - 101,21,160,22,101,20,100,30,161,2,90,23,100,32,90,24, - 100,33,90,25,100,34,103,1,90,26,100,35,103,1,90,27, - 101,27,4,0,90,28,90,29,100,36,102,1,100,36,100,37, - 156,1,100,38,100,39,132,3,90,30,100,40,100,41,132,0, - 90,31,100,42,100,43,132,0,90,32,100,44,100,45,132,0, - 90,33,100,46,100,47,132,0,90,34,100,48,100,49,132,0, - 90,35,100,50,100,51,132,0,90,36,100,52,100,53,132,0, - 90,37,100,54,100,55,132,0,90,38,100,56,100,57,132,0, - 90,39,100,36,100,36,100,36,102,3,100,58,100,59,132,1, - 90,40,100,60,100,60,102,2,100,61,100,62,132,1,90,41, - 100,63,102,1,100,64,100,65,132,1,90,42,100,66,100,67, - 132,0,90,43,101,44,131,0,90,45,100,36,102,1,100,36, - 101,45,100,68,156,2,100,69,100,70,132,3,90,46,71,0, - 100,71,100,72,132,0,100,72,131,2,90,47,71,0,100,73, - 100,74,132,0,100,74,131,2,90,48,71,0,100,75,100,76, - 132,0,100,76,101,48,131,3,90,49,71,0,100,77,100,78, - 132,0,100,78,131,2,90,50,71,0,100,79,100,80,132,0, - 100,80,101,50,101,49,131,4,90,51,71,0,100,81,100,82, - 132,0,100,82,101,50,101,48,131,4,90,52,103,0,90,53, - 71,0,100,83,100,84,132,0,100,84,101,50,101,48,131,4, - 90,54,71,0,100,85,100,86,132,0,100,86,131,2,90,55, - 71,0,100,87,100,88,132,0,100,88,131,2,90,56,71,0, - 100,89,100,90,132,0,100,90,131,2,90,57,71,0,100,91, - 100,92,132,0,100,92,131,2,90,58,100,36,102,1,100,93, - 100,94,132,1,90,59,100,95,100,96,132,0,90,60,100,97, - 100,98,132,0,90,61,100,99,100,100,132,0,90,62,100,36, - 83,0,41,101,97,94,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, - 112,97,116,104,45,98,97,115,101,100,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,41,1,218,3,119,105,110,41,2, - 90,6,99,121,103,119,105,110,90,6,100,97,114,119,105,110, - 99,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,3,0,0,0,115,60,0,0,0,116,0, - 106,1,160,2,116,3,161,1,114,48,116,0,106,1,160,2, - 116,4,161,1,114,30,100,1,137,0,110,4,100,2,137,0, - 135,0,102,1,100,3,100,4,132,8,125,0,110,8,100,5, - 100,4,132,0,125,0,124,0,83,0,41,6,78,90,12,80, - 89,84,72,79,78,67,65,83,69,79,75,115,12,0,0,0, - 80,89,84,72,79,78,67,65,83,69,79,75,99,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,19,0,0,0,115,10,0,0,0,136,0,116,0,106,1, - 107,6,83,0,41,1,250,53,84,114,117,101,32,105,102,32, - 102,105,108,101,110,97,109,101,115,32,109,117,115,116,32,98, - 101,32,99,104,101,99,107,101,100,32,99,97,115,101,45,105, - 110,115,101,110,115,105,116,105,118,101,108,121,46,41,2,218, - 3,95,111,115,90,7,101,110,118,105,114,111,110,169,0,169, - 1,218,3,107,101,121,114,3,0,0,0,250,38,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,95,101,120,116,101,114,110, - 97,108,62,218,11,95,114,101,108,97,120,95,99,97,115,101, - 36,0,0,0,115,2,0,0,0,0,2,122,37,95,109,97, - 107,101,95,114,101,108,97,120,95,99,97,115,101,46,60,108, - 111,99,97,108,115,62,46,95,114,101,108,97,120,95,99,97, - 115,101,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,83,0,0,0,115,4,0,0,0, - 100,1,83,0,41,2,114,1,0,0,0,70,114,3,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,7,0,0,0,40,0,0,0,115,2, - 0,0,0,0,2,41,5,218,3,115,121,115,218,8,112,108, - 97,116,102,111,114,109,218,10,115,116,97,114,116,115,119,105, - 116,104,218,27,95,67,65,83,69,95,73,78,83,69,78,83, - 73,84,73,86,69,95,80,76,65,84,70,79,82,77,83,218, - 35,95,67,65,83,69,95,73,78,83,69,78,83,73,84,73, - 86,69,95,80,76,65,84,70,79,82,77,83,95,83,84,82, - 95,75,69,89,41,1,114,7,0,0,0,114,3,0,0,0, - 114,4,0,0,0,114,6,0,0,0,218,16,95,109,97,107, - 101,95,114,101,108,97,120,95,99,97,115,101,29,0,0,0, - 115,14,0,0,0,0,1,12,1,12,1,6,2,4,2,14, - 4,8,3,114,13,0,0,0,99,1,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,4,0,0,0,67,0,0, - 0,115,20,0,0,0,116,0,124,0,131,1,100,1,64,0, - 160,1,100,2,100,3,161,2,83,0,41,4,122,42,67,111, - 110,118,101,114,116,32,97,32,51,50,45,98,105,116,32,105, - 110,116,101,103,101,114,32,116,111,32,108,105,116,116,108,101, - 45,101,110,100,105,97,110,46,236,3,0,0,0,255,127,255, - 127,3,0,233,4,0,0,0,218,6,108,105,116,116,108,101, - 41,2,218,3,105,110,116,218,8,116,111,95,98,121,116,101, - 115,41,1,218,1,120,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,12,95,112,97,99,107,95,117,105,110, - 116,51,50,46,0,0,0,115,2,0,0,0,0,2,114,20, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,4,0,0,0,67,0,0,0,115,28,0,0, - 0,116,0,124,0,131,1,100,1,107,2,115,16,116,1,130, - 1,116,2,160,3,124,0,100,2,161,2,83,0,41,3,122, - 47,67,111,110,118,101,114,116,32,52,32,98,121,116,101,115, - 32,105,110,32,108,105,116,116,108,101,45,101,110,100,105,97, - 110,32,116,111,32,97,110,32,105,110,116,101,103,101,114,46, - 114,15,0,0,0,114,16,0,0,0,169,4,218,3,108,101, - 110,218,14,65,115,115,101,114,116,105,111,110,69,114,114,111, - 114,114,17,0,0,0,218,10,102,114,111,109,95,98,121,116, - 101,115,169,1,218,4,100,97,116,97,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,14,95,117,110,112,97, - 99,107,95,117,105,110,116,51,50,51,0,0,0,115,4,0, - 0,0,0,2,16,1,114,27,0,0,0,99,1,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0, - 67,0,0,0,115,28,0,0,0,116,0,124,0,131,1,100, - 1,107,2,115,16,116,1,130,1,116,2,160,3,124,0,100, - 2,161,2,83,0,41,3,122,47,67,111,110,118,101,114,116, - 32,50,32,98,121,116,101,115,32,105,110,32,108,105,116,116, - 108,101,45,101,110,100,105,97,110,32,116,111,32,97,110,32, - 105,110,116,101,103,101,114,46,233,2,0,0,0,114,16,0, - 0,0,114,21,0,0,0,114,25,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,14,95,117,110, - 112,97,99,107,95,117,105,110,116,49,54,56,0,0,0,115, - 4,0,0,0,0,2,16,1,114,29,0,0,0,99,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0, - 0,0,71,0,0,0,115,20,0,0,0,116,0,160,1,100, - 1,100,2,132,0,124,0,68,0,131,1,161,1,83,0,41, - 3,122,31,82,101,112,108,97,99,101,109,101,110,116,32,102, - 111,114,32,111,115,46,112,97,116,104,46,106,111,105,110,40, - 41,46,99,1,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,5,0,0,0,83,0,0,0,115,26,0,0,0, - 103,0,124,0,93,18,125,1,124,1,114,22,124,1,160,0, - 116,1,161,1,145,2,113,4,83,0,114,3,0,0,0,41, - 2,218,6,114,115,116,114,105,112,218,15,112,97,116,104,95, - 115,101,112,97,114,97,116,111,114,115,41,2,218,2,46,48, - 218,4,112,97,114,116,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,10,60,108,105,115,116,99,111,109,112, - 62,64,0,0,0,115,6,0,0,0,6,1,2,0,4,255, - 122,30,95,112,97,116,104,95,106,111,105,110,46,60,108,111, - 99,97,108,115,62,46,60,108,105,115,116,99,111,109,112,62, - 41,2,218,8,112,97,116,104,95,115,101,112,218,4,106,111, - 105,110,41,1,218,10,112,97,116,104,95,112,97,114,116,115, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 10,95,112,97,116,104,95,106,111,105,110,62,0,0,0,115, - 6,0,0,0,0,2,10,1,2,255,114,38,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, - 5,0,0,0,67,0,0,0,115,96,0,0,0,116,0,116, - 1,131,1,100,1,107,2,114,36,124,0,160,2,116,3,161, - 1,92,3,125,1,125,2,125,3,124,1,124,3,102,2,83, - 0,116,4,124,0,131,1,68,0,93,42,125,4,124,4,116, - 1,107,6,114,44,124,0,106,5,124,4,100,1,100,2,141, - 2,92,2,125,1,125,3,124,1,124,3,102,2,2,0,1, - 0,83,0,113,44,100,3,124,0,102,2,83,0,41,4,122, - 32,82,101,112,108,97,99,101,109,101,110,116,32,102,111,114, - 32,111,115,46,112,97,116,104,46,115,112,108,105,116,40,41, - 46,233,1,0,0,0,41,1,90,8,109,97,120,115,112,108, - 105,116,218,0,41,6,114,22,0,0,0,114,31,0,0,0, - 218,10,114,112,97,114,116,105,116,105,111,110,114,35,0,0, - 0,218,8,114,101,118,101,114,115,101,100,218,6,114,115,112, - 108,105,116,41,5,218,4,112,97,116,104,90,5,102,114,111, - 110,116,218,1,95,218,4,116,97,105,108,114,19,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 11,95,112,97,116,104,95,115,112,108,105,116,68,0,0,0, - 115,16,0,0,0,0,2,12,1,16,1,8,1,12,1,8, - 1,18,1,14,1,114,47,0,0,0,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,10,0,0,0,116,0,160,1,124,0,161,1, - 83,0,41,1,122,126,83,116,97,116,32,116,104,101,32,112, - 97,116,104,46,10,10,32,32,32,32,77,97,100,101,32,97, - 32,115,101,112,97,114,97,116,101,32,102,117,110,99,116,105, - 111,110,32,116,111,32,109,97,107,101,32,105,116,32,101,97, - 115,105,101,114,32,116,111,32,111,118,101,114,114,105,100,101, - 32,105,110,32,101,120,112,101,114,105,109,101,110,116,115,10, - 32,32,32,32,40,101,46,103,46,32,99,97,99,104,101,32, - 115,116,97,116,32,114,101,115,117,108,116,115,41,46,10,10, - 32,32,32,32,41,2,114,2,0,0,0,90,4,115,116,97, - 116,169,1,114,44,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,10,95,112,97,116,104,95,115, - 116,97,116,80,0,0,0,115,2,0,0,0,0,7,114,49, - 0,0,0,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,50,0,0, - 0,122,12,116,0,124,0,131,1,125,2,87,0,110,22,4, - 0,116,1,107,10,114,34,1,0,1,0,1,0,89,0,100, - 1,83,0,88,0,124,2,106,2,100,2,64,0,124,1,107, - 2,83,0,41,3,122,49,84,101,115,116,32,119,104,101,116, - 104,101,114,32,116,104,101,32,112,97,116,104,32,105,115,32, - 116,104,101,32,115,112,101,99,105,102,105,101,100,32,109,111, - 100,101,32,116,121,112,101,46,70,105,0,240,0,0,41,3, - 114,49,0,0,0,218,7,79,83,69,114,114,111,114,218,7, - 115,116,95,109,111,100,101,41,3,114,44,0,0,0,218,4, - 109,111,100,101,90,9,115,116,97,116,95,105,110,102,111,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,18, - 95,112,97,116,104,95,105,115,95,109,111,100,101,95,116,121, - 112,101,90,0,0,0,115,10,0,0,0,0,2,2,1,12, - 1,14,1,8,1,114,53,0,0,0,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,10,0,0,0,116,0,124,0,100,1,131,2, - 83,0,41,2,122,31,82,101,112,108,97,99,101,109,101,110, - 116,32,102,111,114,32,111,115,46,112,97,116,104,46,105,115, - 102,105,108,101,46,105,0,128,0,0,41,1,114,53,0,0, - 0,114,48,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,12,95,112,97,116,104,95,105,115,102, - 105,108,101,99,0,0,0,115,2,0,0,0,0,2,114,54, - 0,0,0,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,22,0,0, - 0,124,0,115,12,116,0,160,1,161,0,125,0,116,2,124, - 0,100,1,131,2,83,0,41,2,122,30,82,101,112,108,97, - 99,101,109,101,110,116,32,102,111,114,32,111,115,46,112,97, - 116,104,46,105,115,100,105,114,46,105,0,64,0,0,41,3, - 114,2,0,0,0,218,6,103,101,116,99,119,100,114,53,0, - 0,0,114,48,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,218,11,95,112,97,116,104,95,105,115, - 100,105,114,104,0,0,0,115,6,0,0,0,0,2,4,1, - 8,1,114,56,0,0,0,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,26,0,0,0,124,0,160,0,116,1,161,1,112,24,124, - 0,100,1,100,2,133,2,25,0,116,2,107,6,83,0,41, - 3,122,142,82,101,112,108,97,99,101,109,101,110,116,32,102, - 111,114,32,111,115,46,112,97,116,104,46,105,115,97,98,115, - 46,10,10,32,32,32,32,67,111,110,115,105,100,101,114,115, - 32,97,32,87,105,110,100,111,119,115,32,100,114,105,118,101, - 45,114,101,108,97,116,105,118,101,32,112,97,116,104,32,40, - 110,111,32,100,114,105,118,101,44,32,98,117,116,32,115,116, - 97,114,116,115,32,119,105,116,104,32,115,108,97,115,104,41, - 32,116,111,10,32,32,32,32,115,116,105,108,108,32,98,101, - 32,34,97,98,115,111,108,117,116,101,34,46,10,32,32,32, - 32,114,39,0,0,0,233,3,0,0,0,41,3,114,10,0, - 0,0,114,31,0,0,0,218,20,95,112,97,116,104,115,101, - 112,115,95,119,105,116,104,95,99,111,108,111,110,114,48,0, + 90,13,100,23,100,24,132,0,90,14,100,101,100,26,100,27, + 132,1,90,15,101,16,101,15,106,17,131,1,90,18,100,28, + 160,19,100,29,100,30,161,2,100,31,23,0,90,20,101,21, + 160,22,101,20,100,30,161,2,90,23,100,32,90,24,100,33, + 90,25,100,34,103,1,90,26,100,35,103,1,90,27,101,27, + 4,0,90,28,90,29,100,102,100,36,100,37,156,1,100,38, + 100,39,132,3,90,30,100,40,100,41,132,0,90,31,100,42, + 100,43,132,0,90,32,100,44,100,45,132,0,90,33,100,46, + 100,47,132,0,90,34,100,48,100,49,132,0,90,35,100,50, + 100,51,132,0,90,36,100,52,100,53,132,0,90,37,100,54, + 100,55,132,0,90,38,100,56,100,57,132,0,90,39,100,103, + 100,58,100,59,132,1,90,40,100,104,100,61,100,62,132,1, + 90,41,100,105,100,64,100,65,132,1,90,42,100,66,100,67, + 132,0,90,43,101,44,131,0,90,45,100,106,100,36,101,45, + 100,68,156,2,100,69,100,70,132,3,90,46,71,0,100,71, + 100,72,132,0,100,72,131,2,90,47,71,0,100,73,100,74, + 132,0,100,74,131,2,90,48,71,0,100,75,100,76,132,0, + 100,76,101,48,131,3,90,49,71,0,100,77,100,78,132,0, + 100,78,131,2,90,50,71,0,100,79,100,80,132,0,100,80, + 101,50,101,49,131,4,90,51,71,0,100,81,100,82,132,0, + 100,82,101,50,101,48,131,4,90,52,103,0,90,53,71,0, + 100,83,100,84,132,0,100,84,101,50,101,48,131,4,90,54, + 71,0,100,85,100,86,132,0,100,86,131,2,90,55,71,0, + 100,87,100,88,132,0,100,88,131,2,90,56,71,0,100,89, + 100,90,132,0,100,90,131,2,90,57,71,0,100,91,100,92, + 132,0,100,92,131,2,90,58,100,107,100,93,100,94,132,1, + 90,59,100,95,100,96,132,0,90,60,100,97,100,98,132,0, + 90,61,100,99,100,100,132,0,90,62,100,36,83,0,41,108, + 97,94,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,112,97,116,104, + 45,98,97,115,101,100,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,41,1,218,3,119,105,110,41,2,90,6,99,121, + 103,119,105,110,90,6,100,97,114,119,105,110,99,0,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0, + 0,3,0,0,0,115,60,0,0,0,116,0,106,1,160,2, + 116,3,161,1,114,48,116,0,106,1,160,2,116,4,161,1, + 114,30,100,1,137,0,110,4,100,2,137,0,135,0,102,1, + 100,3,100,4,132,8,125,0,110,8,100,5,100,4,132,0, + 125,0,124,0,83,0,41,6,78,90,12,80,89,84,72,79, + 78,67,65,83,69,79,75,115,12,0,0,0,80,89,84,72, + 79,78,67,65,83,69,79,75,99,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,19,0,0, + 0,115,10,0,0,0,136,0,116,0,106,1,107,6,83,0, + 41,1,250,53,84,114,117,101,32,105,102,32,102,105,108,101, + 110,97,109,101,115,32,109,117,115,116,32,98,101,32,99,104, + 101,99,107,101,100,32,99,97,115,101,45,105,110,115,101,110, + 115,105,116,105,118,101,108,121,46,41,2,218,3,95,111,115, + 90,7,101,110,118,105,114,111,110,169,0,169,1,218,3,107, + 101,121,114,3,0,0,0,250,38,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,95,101,120,116,101,114,110,97,108,62,218, + 11,95,114,101,108,97,120,95,99,97,115,101,36,0,0,0, + 115,2,0,0,0,0,2,122,37,95,109,97,107,101,95,114, + 101,108,97,120,95,99,97,115,101,46,60,108,111,99,97,108, + 115,62,46,95,114,101,108,97,120,95,99,97,115,101,99,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,83,0,0,0,115,4,0,0,0,100,1,83,0, + 41,2,114,1,0,0,0,70,114,3,0,0,0,114,3,0, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,11,95,112,97,116,104,95,105,115,97,98,115,111,0, - 0,0,115,2,0,0,0,0,6,114,59,0,0,0,233,182, - 1,0,0,99,3,0,0,0,0,0,0,0,0,0,0,0, - 6,0,0,0,11,0,0,0,67,0,0,0,115,162,0,0, - 0,100,1,160,0,124,0,116,1,124,0,131,1,161,2,125, - 3,116,2,160,3,124,3,116,2,106,4,116,2,106,5,66, - 0,116,2,106,6,66,0,124,2,100,2,64,0,161,3,125, - 4,122,50,116,7,160,8,124,4,100,3,161,2,143,16,125, - 5,124,5,160,9,124,1,161,1,1,0,87,0,53,0,81, - 0,82,0,88,0,116,2,160,10,124,3,124,0,161,2,1, - 0,87,0,110,58,4,0,116,11,107,10,114,156,1,0,1, - 0,1,0,122,14,116,2,160,12,124,3,161,1,1,0,87, - 0,110,20,4,0,116,11,107,10,114,148,1,0,1,0,1, - 0,89,0,110,2,88,0,130,0,89,0,110,2,88,0,100, - 4,83,0,41,5,122,162,66,101,115,116,45,101,102,102,111, - 114,116,32,102,117,110,99,116,105,111,110,32,116,111,32,119, - 114,105,116,101,32,100,97,116,97,32,116,111,32,97,32,112, - 97,116,104,32,97,116,111,109,105,99,97,108,108,121,46,10, - 32,32,32,32,66,101,32,112,114,101,112,97,114,101,100,32, - 116,111,32,104,97,110,100,108,101,32,97,32,70,105,108,101, - 69,120,105,115,116,115,69,114,114,111,114,32,105,102,32,99, - 111,110,99,117,114,114,101,110,116,32,119,114,105,116,105,110, - 103,32,111,102,32,116,104,101,10,32,32,32,32,116,101,109, - 112,111,114,97,114,121,32,102,105,108,101,32,105,115,32,97, - 116,116,101,109,112,116,101,100,46,250,5,123,125,46,123,125, - 114,60,0,0,0,90,2,119,98,78,41,13,218,6,102,111, - 114,109,97,116,218,2,105,100,114,2,0,0,0,90,4,111, - 112,101,110,90,6,79,95,69,88,67,76,90,7,79,95,67, - 82,69,65,84,90,8,79,95,87,82,79,78,76,89,218,3, - 95,105,111,218,6,70,105,108,101,73,79,218,5,119,114,105, - 116,101,218,7,114,101,112,108,97,99,101,114,50,0,0,0, - 90,6,117,110,108,105,110,107,41,6,114,44,0,0,0,114, - 26,0,0,0,114,52,0,0,0,90,8,112,97,116,104,95, - 116,109,112,90,2,102,100,218,4,102,105,108,101,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,13,95,119, - 114,105,116,101,95,97,116,111,109,105,99,120,0,0,0,115, - 30,0,0,0,0,5,16,1,6,1,16,0,6,255,4,2, - 2,3,14,1,20,1,16,1,14,1,2,1,14,1,14,1, - 6,1,114,69,0,0,0,105,82,13,0,0,114,28,0,0, - 0,114,16,0,0,0,115,2,0,0,0,13,10,90,11,95, - 95,112,121,99,97,99,104,101,95,95,122,4,111,112,116,45, - 122,3,46,112,121,122,4,46,112,121,99,78,41,1,218,12, - 111,112,116,105,109,105,122,97,116,105,111,110,99,2,0,0, - 0,0,0,0,0,1,0,0,0,12,0,0,0,5,0,0, - 0,67,0,0,0,115,88,1,0,0,124,1,100,1,107,9, - 114,52,116,0,160,1,100,2,116,2,161,2,1,0,124,2, - 100,1,107,9,114,40,100,3,125,3,116,3,124,3,131,1, - 130,1,124,1,114,48,100,4,110,2,100,5,125,2,116,4, - 160,5,124,0,161,1,125,0,116,6,124,0,131,1,92,2, - 125,4,125,5,124,5,160,7,100,6,161,1,92,3,125,6, - 125,7,125,8,116,8,106,9,106,10,125,9,124,9,100,1, - 107,8,114,114,116,11,100,7,131,1,130,1,100,4,160,12, - 124,6,114,126,124,6,110,2,124,8,124,7,124,9,103,3, - 161,1,125,10,124,2,100,1,107,8,114,172,116,8,106,13, - 106,14,100,8,107,2,114,164,100,4,125,2,110,8,116,8, - 106,13,106,14,125,2,116,15,124,2,131,1,125,2,124,2, - 100,4,107,3,114,224,124,2,160,16,161,0,115,210,116,17, - 100,9,160,18,124,2,161,1,131,1,130,1,100,10,160,18, - 124,10,116,19,124,2,161,3,125,10,124,10,116,20,100,8, - 25,0,23,0,125,11,116,8,106,21,100,1,107,9,144,1, - 114,76,116,22,124,4,131,1,144,1,115,16,116,23,116,4, - 160,24,161,0,124,4,131,2,125,4,124,4,100,5,25,0, - 100,11,107,2,144,1,114,56,124,4,100,8,25,0,116,25, - 107,7,144,1,114,56,124,4,100,12,100,1,133,2,25,0, - 125,4,116,23,116,8,106,21,124,4,160,26,116,25,161,1, - 124,11,131,3,83,0,116,23,124,4,116,27,124,11,131,3, - 83,0,41,13,97,254,2,0,0,71,105,118,101,110,32,116, - 104,101,32,112,97,116,104,32,116,111,32,97,32,46,112,121, - 32,102,105,108,101,44,32,114,101,116,117,114,110,32,116,104, - 101,32,112,97,116,104,32,116,111,32,105,116,115,32,46,112, - 121,99,32,102,105,108,101,46,10,10,32,32,32,32,84,104, - 101,32,46,112,121,32,102,105,108,101,32,100,111,101,115,32, - 110,111,116,32,110,101,101,100,32,116,111,32,101,120,105,115, - 116,59,32,116,104,105,115,32,115,105,109,112,108,121,32,114, - 101,116,117,114,110,115,32,116,104,101,32,112,97,116,104,32, - 116,111,32,116,104,101,10,32,32,32,32,46,112,121,99,32, - 102,105,108,101,32,99,97,108,99,117,108,97,116,101,100,32, - 97,115,32,105,102,32,116,104,101,32,46,112,121,32,102,105, - 108,101,32,119,101,114,101,32,105,109,112,111,114,116,101,100, - 46,10,10,32,32,32,32,84,104,101,32,39,111,112,116,105, - 109,105,122,97,116,105,111,110,39,32,112,97,114,97,109,101, - 116,101,114,32,99,111,110,116,114,111,108,115,32,116,104,101, - 32,112,114,101,115,117,109,101,100,32,111,112,116,105,109,105, - 122,97,116,105,111,110,32,108,101,118,101,108,32,111,102,10, - 32,32,32,32,116,104,101,32,98,121,116,101,99,111,100,101, - 32,102,105,108,101,46,32,73,102,32,39,111,112,116,105,109, - 105,122,97,116,105,111,110,39,32,105,115,32,110,111,116,32, - 78,111,110,101,44,32,116,104,101,32,115,116,114,105,110,103, - 32,114,101,112,114,101,115,101,110,116,97,116,105,111,110,10, - 32,32,32,32,111,102,32,116,104,101,32,97,114,103,117,109, - 101,110,116,32,105,115,32,116,97,107,101,110,32,97,110,100, - 32,118,101,114,105,102,105,101,100,32,116,111,32,98,101,32, - 97,108,112,104,97,110,117,109,101,114,105,99,32,40,101,108, - 115,101,32,86,97,108,117,101,69,114,114,111,114,10,32,32, - 32,32,105,115,32,114,97,105,115,101,100,41,46,10,10,32, - 32,32,32,84,104,101,32,100,101,98,117,103,95,111,118,101, - 114,114,105,100,101,32,112,97,114,97,109,101,116,101,114,32, - 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,73, - 102,32,100,101,98,117,103,95,111,118,101,114,114,105,100,101, - 32,105,115,32,110,111,116,32,78,111,110,101,44,10,32,32, - 32,32,97,32,84,114,117,101,32,118,97,108,117,101,32,105, - 115,32,116,104,101,32,115,97,109,101,32,97,115,32,115,101, + 0,114,7,0,0,0,40,0,0,0,115,2,0,0,0,0, + 2,41,5,218,3,115,121,115,218,8,112,108,97,116,102,111, + 114,109,218,10,115,116,97,114,116,115,119,105,116,104,218,27, + 95,67,65,83,69,95,73,78,83,69,78,83,73,84,73,86, + 69,95,80,76,65,84,70,79,82,77,83,218,35,95,67,65, + 83,69,95,73,78,83,69,78,83,73,84,73,86,69,95,80, + 76,65,84,70,79,82,77,83,95,83,84,82,95,75,69,89, + 41,1,114,7,0,0,0,114,3,0,0,0,114,4,0,0, + 0,114,6,0,0,0,218,16,95,109,97,107,101,95,114,101, + 108,97,120,95,99,97,115,101,29,0,0,0,115,14,0,0, + 0,0,1,12,1,12,1,6,2,4,2,14,4,8,3,114, + 13,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,4,0,0,0,67,0,0,0,115,20,0, + 0,0,116,0,124,0,131,1,100,1,64,0,160,1,100,2, + 100,3,161,2,83,0,41,4,122,42,67,111,110,118,101,114, + 116,32,97,32,51,50,45,98,105,116,32,105,110,116,101,103, + 101,114,32,116,111,32,108,105,116,116,108,101,45,101,110,100, + 105,97,110,46,236,3,0,0,0,255,127,255,127,3,0,233, + 4,0,0,0,218,6,108,105,116,116,108,101,41,2,218,3, + 105,110,116,218,8,116,111,95,98,121,116,101,115,41,1,218, + 1,120,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,12,95,112,97,99,107,95,117,105,110,116,51,50,46, + 0,0,0,115,2,0,0,0,0,2,114,20,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 4,0,0,0,67,0,0,0,115,28,0,0,0,116,0,124, + 0,131,1,100,1,107,2,115,16,116,1,130,1,116,2,160, + 3,124,0,100,2,161,2,83,0,41,3,122,47,67,111,110, + 118,101,114,116,32,52,32,98,121,116,101,115,32,105,110,32, + 108,105,116,116,108,101,45,101,110,100,105,97,110,32,116,111, + 32,97,110,32,105,110,116,101,103,101,114,46,114,15,0,0, + 0,114,16,0,0,0,169,4,218,3,108,101,110,218,14,65, + 115,115,101,114,116,105,111,110,69,114,114,111,114,114,17,0, + 0,0,218,10,102,114,111,109,95,98,121,116,101,115,169,1, + 218,4,100,97,116,97,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,14,95,117,110,112,97,99,107,95,117, + 105,110,116,51,50,51,0,0,0,115,4,0,0,0,0,2, + 16,1,114,27,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,4,0,0,0,67,0,0,0, + 115,28,0,0,0,116,0,124,0,131,1,100,1,107,2,115, + 16,116,1,130,1,116,2,160,3,124,0,100,2,161,2,83, + 0,41,3,122,47,67,111,110,118,101,114,116,32,50,32,98, + 121,116,101,115,32,105,110,32,108,105,116,116,108,101,45,101, + 110,100,105,97,110,32,116,111,32,97,110,32,105,110,116,101, + 103,101,114,46,233,2,0,0,0,114,16,0,0,0,114,21, + 0,0,0,114,25,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,218,14,95,117,110,112,97,99,107, + 95,117,105,110,116,49,54,56,0,0,0,115,4,0,0,0, + 0,2,16,1,114,29,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,4,0,0,0,71,0, + 0,0,115,20,0,0,0,116,0,160,1,100,1,100,2,132, + 0,124,0,68,0,131,1,161,1,83,0,41,3,122,31,82, + 101,112,108,97,99,101,109,101,110,116,32,102,111,114,32,111, + 115,46,112,97,116,104,46,106,111,105,110,40,41,46,99,1, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,5, + 0,0,0,83,0,0,0,115,26,0,0,0,103,0,124,0, + 93,18,125,1,124,1,114,4,124,1,160,0,116,1,161,1, + 145,2,113,4,83,0,114,3,0,0,0,41,2,218,6,114, + 115,116,114,105,112,218,15,112,97,116,104,95,115,101,112,97, + 114,97,116,111,114,115,41,2,218,2,46,48,218,4,112,97, + 114,116,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,10,60,108,105,115,116,99,111,109,112,62,64,0,0, + 0,115,6,0,0,0,6,1,2,0,4,255,122,30,95,112, + 97,116,104,95,106,111,105,110,46,60,108,111,99,97,108,115, + 62,46,60,108,105,115,116,99,111,109,112,62,41,2,218,8, + 112,97,116,104,95,115,101,112,218,4,106,111,105,110,41,1, + 218,10,112,97,116,104,95,112,97,114,116,115,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,10,95,112,97, + 116,104,95,106,111,105,110,62,0,0,0,115,6,0,0,0, + 0,2,10,1,2,255,114,38,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, + 67,0,0,0,115,96,0,0,0,116,0,116,1,131,1,100, + 1,107,2,114,36,124,0,160,2,116,3,161,1,92,3,125, + 1,125,2,125,3,124,1,124,3,102,2,83,0,116,4,124, + 0,131,1,68,0,93,42,125,4,124,4,116,1,107,6,114, + 44,124,0,106,5,124,4,100,1,100,2,141,2,92,2,125, + 1,125,3,124,1,124,3,102,2,2,0,1,0,83,0,113, + 44,100,3,124,0,102,2,83,0,41,4,122,32,82,101,112, + 108,97,99,101,109,101,110,116,32,102,111,114,32,111,115,46, + 112,97,116,104,46,115,112,108,105,116,40,41,46,233,1,0, + 0,0,41,1,90,8,109,97,120,115,112,108,105,116,218,0, + 41,6,114,22,0,0,0,114,31,0,0,0,218,10,114,112, + 97,114,116,105,116,105,111,110,114,35,0,0,0,218,8,114, + 101,118,101,114,115,101,100,218,6,114,115,112,108,105,116,41, + 5,218,4,112,97,116,104,90,5,102,114,111,110,116,218,1, + 95,218,4,116,97,105,108,114,19,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,11,95,112,97, + 116,104,95,115,112,108,105,116,68,0,0,0,115,16,0,0, + 0,0,2,12,1,16,1,8,1,12,1,8,1,18,1,14, + 1,114,47,0,0,0,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, + 10,0,0,0,116,0,160,1,124,0,161,1,83,0,41,1, + 122,126,83,116,97,116,32,116,104,101,32,112,97,116,104,46, + 10,10,32,32,32,32,77,97,100,101,32,97,32,115,101,112, + 97,114,97,116,101,32,102,117,110,99,116,105,111,110,32,116, + 111,32,109,97,107,101,32,105,116,32,101,97,115,105,101,114, + 32,116,111,32,111,118,101,114,114,105,100,101,32,105,110,32, + 101,120,112,101,114,105,109,101,110,116,115,10,32,32,32,32, + 40,101,46,103,46,32,99,97,99,104,101,32,115,116,97,116, + 32,114,101,115,117,108,116,115,41,46,10,10,32,32,32,32, + 41,2,114,2,0,0,0,90,4,115,116,97,116,169,1,114, + 44,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,218,10,95,112,97,116,104,95,115,116,97,116,80, + 0,0,0,115,2,0,0,0,0,7,114,49,0,0,0,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,50,0,0,0,122,12,116, + 0,124,0,131,1,125,2,87,0,110,22,4,0,116,1,107, + 10,114,34,1,0,1,0,1,0,89,0,100,1,83,0,88, + 0,124,2,106,2,100,2,64,0,124,1,107,2,83,0,41, + 3,122,49,84,101,115,116,32,119,104,101,116,104,101,114,32, + 116,104,101,32,112,97,116,104,32,105,115,32,116,104,101,32, + 115,112,101,99,105,102,105,101,100,32,109,111,100,101,32,116, + 121,112,101,46,70,105,0,240,0,0,41,3,114,49,0,0, + 0,218,7,79,83,69,114,114,111,114,218,7,115,116,95,109, + 111,100,101,41,3,114,44,0,0,0,218,4,109,111,100,101, + 90,9,115,116,97,116,95,105,110,102,111,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,18,95,112,97,116, + 104,95,105,115,95,109,111,100,101,95,116,121,112,101,90,0, + 0,0,115,10,0,0,0,0,2,2,1,12,1,14,1,8, + 1,114,53,0,0,0,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, + 10,0,0,0,116,0,124,0,100,1,131,2,83,0,41,2, + 122,31,82,101,112,108,97,99,101,109,101,110,116,32,102,111, + 114,32,111,115,46,112,97,116,104,46,105,115,102,105,108,101, + 46,105,0,128,0,0,41,1,114,53,0,0,0,114,48,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,12,95,112,97,116,104,95,105,115,102,105,108,101,99, + 0,0,0,115,2,0,0,0,0,2,114,54,0,0,0,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,22,0,0,0,124,0,115, + 12,116,0,160,1,161,0,125,0,116,2,124,0,100,1,131, + 2,83,0,41,2,122,30,82,101,112,108,97,99,101,109,101, + 110,116,32,102,111,114,32,111,115,46,112,97,116,104,46,105, + 115,100,105,114,46,105,0,64,0,0,41,3,114,2,0,0, + 0,218,6,103,101,116,99,119,100,114,53,0,0,0,114,48, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,11,95,112,97,116,104,95,105,115,100,105,114,104, + 0,0,0,115,6,0,0,0,0,2,4,1,8,1,114,56, + 0,0,0,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,26,0,0, + 0,124,0,160,0,116,1,161,1,112,24,124,0,100,1,100, + 2,133,2,25,0,116,2,107,6,83,0,41,3,122,142,82, + 101,112,108,97,99,101,109,101,110,116,32,102,111,114,32,111, + 115,46,112,97,116,104,46,105,115,97,98,115,46,10,10,32, + 32,32,32,67,111,110,115,105,100,101,114,115,32,97,32,87, + 105,110,100,111,119,115,32,100,114,105,118,101,45,114,101,108, + 97,116,105,118,101,32,112,97,116,104,32,40,110,111,32,100, + 114,105,118,101,44,32,98,117,116,32,115,116,97,114,116,115, + 32,119,105,116,104,32,115,108,97,115,104,41,32,116,111,10, + 32,32,32,32,115,116,105,108,108,32,98,101,32,34,97,98, + 115,111,108,117,116,101,34,46,10,32,32,32,32,114,39,0, + 0,0,233,3,0,0,0,41,3,114,10,0,0,0,114,31, + 0,0,0,218,20,95,112,97,116,104,115,101,112,115,95,119, + 105,116,104,95,99,111,108,111,110,114,48,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,11,95, + 112,97,116,104,95,105,115,97,98,115,111,0,0,0,115,2, + 0,0,0,0,6,114,59,0,0,0,233,182,1,0,0,99, + 3,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, + 11,0,0,0,67,0,0,0,115,162,0,0,0,100,1,160, + 0,124,0,116,1,124,0,131,1,161,2,125,3,116,2,160, + 3,124,3,116,2,106,4,116,2,106,5,66,0,116,2,106, + 6,66,0,124,2,100,2,64,0,161,3,125,4,122,50,116, + 7,160,8,124,4,100,3,161,2,143,16,125,5,124,5,160, + 9,124,1,161,1,1,0,87,0,53,0,81,0,82,0,88, + 0,116,2,160,10,124,3,124,0,161,2,1,0,87,0,110, + 58,4,0,116,11,107,10,114,156,1,0,1,0,1,0,122, + 14,116,2,160,12,124,3,161,1,1,0,87,0,110,20,4, + 0,116,11,107,10,114,148,1,0,1,0,1,0,89,0,110, + 2,88,0,130,0,89,0,110,2,88,0,100,4,83,0,41, + 5,122,162,66,101,115,116,45,101,102,102,111,114,116,32,102, + 117,110,99,116,105,111,110,32,116,111,32,119,114,105,116,101, + 32,100,97,116,97,32,116,111,32,97,32,112,97,116,104,32, + 97,116,111,109,105,99,97,108,108,121,46,10,32,32,32,32, + 66,101,32,112,114,101,112,97,114,101,100,32,116,111,32,104, + 97,110,100,108,101,32,97,32,70,105,108,101,69,120,105,115, + 116,115,69,114,114,111,114,32,105,102,32,99,111,110,99,117, + 114,114,101,110,116,32,119,114,105,116,105,110,103,32,111,102, + 32,116,104,101,10,32,32,32,32,116,101,109,112,111,114,97, + 114,121,32,102,105,108,101,32,105,115,32,97,116,116,101,109, + 112,116,101,100,46,250,5,123,125,46,123,125,114,60,0,0, + 0,90,2,119,98,78,41,13,218,6,102,111,114,109,97,116, + 218,2,105,100,114,2,0,0,0,90,4,111,112,101,110,90, + 6,79,95,69,88,67,76,90,7,79,95,67,82,69,65,84, + 90,8,79,95,87,82,79,78,76,89,218,3,95,105,111,218, + 6,70,105,108,101,73,79,218,5,119,114,105,116,101,218,7, + 114,101,112,108,97,99,101,114,50,0,0,0,90,6,117,110, + 108,105,110,107,41,6,114,44,0,0,0,114,26,0,0,0, + 114,52,0,0,0,90,8,112,97,116,104,95,116,109,112,90, + 2,102,100,218,4,102,105,108,101,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,13,95,119,114,105,116,101, + 95,97,116,111,109,105,99,120,0,0,0,115,30,0,0,0, + 0,5,16,1,6,1,16,0,6,255,4,2,2,3,14,1, + 20,1,16,1,14,1,2,1,14,1,14,1,6,1,114,69, + 0,0,0,105,85,13,0,0,114,28,0,0,0,114,16,0, + 0,0,115,2,0,0,0,13,10,90,11,95,95,112,121,99, + 97,99,104,101,95,95,122,4,111,112,116,45,122,3,46,112, + 121,122,4,46,112,121,99,78,41,1,218,12,111,112,116,105, + 109,105,122,97,116,105,111,110,99,2,0,0,0,0,0,0, + 0,1,0,0,0,12,0,0,0,5,0,0,0,67,0,0, + 0,115,88,1,0,0,124,1,100,1,107,9,114,52,116,0, + 160,1,100,2,116,2,161,2,1,0,124,2,100,1,107,9, + 114,40,100,3,125,3,116,3,124,3,131,1,130,1,124,1, + 114,48,100,4,110,2,100,5,125,2,116,4,160,5,124,0, + 161,1,125,0,116,6,124,0,131,1,92,2,125,4,125,5, + 124,5,160,7,100,6,161,1,92,3,125,6,125,7,125,8, + 116,8,106,9,106,10,125,9,124,9,100,1,107,8,114,114, + 116,11,100,7,131,1,130,1,100,4,160,12,124,6,114,126, + 124,6,110,2,124,8,124,7,124,9,103,3,161,1,125,10, + 124,2,100,1,107,8,114,172,116,8,106,13,106,14,100,8, + 107,2,114,164,100,4,125,2,110,8,116,8,106,13,106,14, + 125,2,116,15,124,2,131,1,125,2,124,2,100,4,107,3, + 114,224,124,2,160,16,161,0,115,210,116,17,100,9,160,18, + 124,2,161,1,131,1,130,1,100,10,160,18,124,10,116,19, + 124,2,161,3,125,10,124,10,116,20,100,8,25,0,23,0, + 125,11,116,8,106,21,100,1,107,9,144,1,114,76,116,22, + 124,4,131,1,144,1,115,16,116,23,116,4,160,24,161,0, + 124,4,131,2,125,4,124,4,100,5,25,0,100,11,107,2, + 144,1,114,56,124,4,100,8,25,0,116,25,107,7,144,1, + 114,56,124,4,100,12,100,1,133,2,25,0,125,4,116,23, + 116,8,106,21,124,4,160,26,116,25,161,1,124,11,131,3, + 83,0,116,23,124,4,116,27,124,11,131,3,83,0,41,13, + 97,254,2,0,0,71,105,118,101,110,32,116,104,101,32,112, + 97,116,104,32,116,111,32,97,32,46,112,121,32,102,105,108, + 101,44,32,114,101,116,117,114,110,32,116,104,101,32,112,97, + 116,104,32,116,111,32,105,116,115,32,46,112,121,99,32,102, + 105,108,101,46,10,10,32,32,32,32,84,104,101,32,46,112, + 121,32,102,105,108,101,32,100,111,101,115,32,110,111,116,32, + 110,101,101,100,32,116,111,32,101,120,105,115,116,59,32,116, + 104,105,115,32,115,105,109,112,108,121,32,114,101,116,117,114, + 110,115,32,116,104,101,32,112,97,116,104,32,116,111,32,116, + 104,101,10,32,32,32,32,46,112,121,99,32,102,105,108,101, + 32,99,97,108,99,117,108,97,116,101,100,32,97,115,32,105, + 102,32,116,104,101,32,46,112,121,32,102,105,108,101,32,119, + 101,114,101,32,105,109,112,111,114,116,101,100,46,10,10,32, + 32,32,32,84,104,101,32,39,111,112,116,105,109,105,122,97, + 116,105,111,110,39,32,112,97,114,97,109,101,116,101,114,32, + 99,111,110,116,114,111,108,115,32,116,104,101,32,112,114,101, + 115,117,109,101,100,32,111,112,116,105,109,105,122,97,116,105, + 111,110,32,108,101,118,101,108,32,111,102,10,32,32,32,32, + 116,104,101,32,98,121,116,101,99,111,100,101,32,102,105,108, + 101,46,32,73,102,32,39,111,112,116,105,109,105,122,97,116, + 105,111,110,39,32,105,115,32,110,111,116,32,78,111,110,101, + 44,32,116,104,101,32,115,116,114,105,110,103,32,114,101,112, + 114,101,115,101,110,116,97,116,105,111,110,10,32,32,32,32, + 111,102,32,116,104,101,32,97,114,103,117,109,101,110,116,32, + 105,115,32,116,97,107,101,110,32,97,110,100,32,118,101,114, + 105,102,105,101,100,32,116,111,32,98,101,32,97,108,112,104, + 97,110,117,109,101,114,105,99,32,40,101,108,115,101,32,86, + 97,108,117,101,69,114,114,111,114,10,32,32,32,32,105,115, + 32,114,97,105,115,101,100,41,46,10,10,32,32,32,32,84, + 104,101,32,100,101,98,117,103,95,111,118,101,114,114,105,100, + 101,32,112,97,114,97,109,101,116,101,114,32,105,115,32,100, + 101,112,114,101,99,97,116,101,100,46,32,73,102,32,100,101, + 98,117,103,95,111,118,101,114,114,105,100,101,32,105,115,32, + 110,111,116,32,78,111,110,101,44,10,32,32,32,32,97,32, + 84,114,117,101,32,118,97,108,117,101,32,105,115,32,116,104, + 101,32,115,97,109,101,32,97,115,32,115,101,116,116,105,110, + 103,32,39,111,112,116,105,109,105,122,97,116,105,111,110,39, + 32,116,111,32,116,104,101,32,101,109,112,116,121,32,115,116, + 114,105,110,103,10,32,32,32,32,119,104,105,108,101,32,97, + 32,70,97,108,115,101,32,118,97,108,117,101,32,105,115,32, + 101,113,117,105,118,97,108,101,110,116,32,116,111,32,115,101, 116,116,105,110,103,32,39,111,112,116,105,109,105,122,97,116, - 105,111,110,39,32,116,111,32,116,104,101,32,101,109,112,116, - 121,32,115,116,114,105,110,103,10,32,32,32,32,119,104,105, - 108,101,32,97,32,70,97,108,115,101,32,118,97,108,117,101, - 32,105,115,32,101,113,117,105,118,97,108,101,110,116,32,116, - 111,32,115,101,116,116,105,110,103,32,39,111,112,116,105,109, - 105,122,97,116,105,111,110,39,32,116,111,32,39,49,39,46, - 10,10,32,32,32,32,73,102,32,115,121,115,46,105,109,112, - 108,101,109,101,110,116,97,116,105,111,110,46,99,97,99,104, - 101,95,116,97,103,32,105,115,32,78,111,110,101,32,116,104, - 101,110,32,78,111,116,73,109,112,108,101,109,101,110,116,101, - 100,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, - 46,10,10,32,32,32,32,78,122,70,116,104,101,32,100,101, - 98,117,103,95,111,118,101,114,114,105,100,101,32,112,97,114, - 97,109,101,116,101,114,32,105,115,32,100,101,112,114,101,99, - 97,116,101,100,59,32,117,115,101,32,39,111,112,116,105,109, - 105,122,97,116,105,111,110,39,32,105,110,115,116,101,97,100, - 122,50,100,101,98,117,103,95,111,118,101,114,114,105,100,101, - 32,111,114,32,111,112,116,105,109,105,122,97,116,105,111,110, - 32,109,117,115,116,32,98,101,32,115,101,116,32,116,111,32, - 78,111,110,101,114,40,0,0,0,114,39,0,0,0,218,1, - 46,250,36,115,121,115,46,105,109,112,108,101,109,101,110,116, - 97,116,105,111,110,46,99,97,99,104,101,95,116,97,103,32, - 105,115,32,78,111,110,101,233,0,0,0,0,122,24,123,33, - 114,125,32,105,115,32,110,111,116,32,97,108,112,104,97,110, - 117,109,101,114,105,99,122,7,123,125,46,123,125,123,125,250, - 1,58,114,28,0,0,0,41,28,218,9,95,119,97,114,110, - 105,110,103,115,218,4,119,97,114,110,218,18,68,101,112,114, - 101,99,97,116,105,111,110,87,97,114,110,105,110,103,218,9, - 84,121,112,101,69,114,114,111,114,114,2,0,0,0,218,6, - 102,115,112,97,116,104,114,47,0,0,0,114,41,0,0,0, - 114,8,0,0,0,218,14,105,109,112,108,101,109,101,110,116, - 97,116,105,111,110,218,9,99,97,99,104,101,95,116,97,103, - 218,19,78,111,116,73,109,112,108,101,109,101,110,116,101,100, - 69,114,114,111,114,114,36,0,0,0,218,5,102,108,97,103, - 115,218,8,111,112,116,105,109,105,122,101,218,3,115,116,114, - 218,7,105,115,97,108,110,117,109,218,10,86,97,108,117,101, - 69,114,114,111,114,114,62,0,0,0,218,4,95,79,80,84, - 218,17,66,89,84,69,67,79,68,69,95,83,85,70,70,73, - 88,69,83,218,14,112,121,99,97,99,104,101,95,112,114,101, - 102,105,120,114,59,0,0,0,114,38,0,0,0,114,55,0, - 0,0,114,31,0,0,0,218,6,108,115,116,114,105,112,218, - 8,95,80,89,67,65,67,72,69,41,12,114,44,0,0,0, - 90,14,100,101,98,117,103,95,111,118,101,114,114,105,100,101, - 114,70,0,0,0,218,7,109,101,115,115,97,103,101,218,4, - 104,101,97,100,114,46,0,0,0,90,4,98,97,115,101,218, - 3,115,101,112,218,4,114,101,115,116,90,3,116,97,103,90, - 15,97,108,109,111,115,116,95,102,105,108,101,110,97,109,101, - 218,8,102,105,108,101,110,97,109,101,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,17,99,97,99,104,101, - 95,102,114,111,109,95,115,111,117,114,99,101,33,1,0,0, - 115,72,0,0,0,0,18,8,1,6,1,2,255,4,2,8, - 1,4,1,8,1,12,1,10,1,12,1,16,1,8,1,8, - 1,8,1,24,1,8,1,12,1,6,2,8,1,8,1,8, - 1,8,1,14,1,14,1,12,1,12,9,10,1,14,5,28, - 1,12,4,2,1,4,1,8,1,2,253,4,5,114,98,0, - 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,10, - 0,0,0,5,0,0,0,67,0,0,0,115,46,1,0,0, - 116,0,106,1,106,2,100,1,107,8,114,20,116,3,100,2, - 131,1,130,1,116,4,160,5,124,0,161,1,125,0,116,6, - 124,0,131,1,92,2,125,1,125,2,100,3,125,3,116,0, - 106,7,100,1,107,9,114,102,116,0,106,7,160,8,116,9, - 161,1,125,4,124,1,160,10,124,4,116,11,23,0,161,1, - 114,102,124,1,116,12,124,4,131,1,100,1,133,2,25,0, - 125,1,100,4,125,3,124,3,115,144,116,6,124,1,131,1, - 92,2,125,1,125,5,124,5,116,13,107,3,114,144,116,14, - 116,13,155,0,100,5,124,0,155,2,157,3,131,1,130,1, - 124,2,160,15,100,6,161,1,125,6,124,6,100,7,107,7, - 114,178,116,14,100,8,124,2,155,2,157,2,131,1,130,1, - 110,92,124,6,100,9,107,2,144,1,114,14,124,2,160,16, - 100,6,100,10,161,2,100,11,25,0,125,7,124,7,160,10, - 116,17,161,1,115,228,116,14,100,12,116,17,155,2,157,2, - 131,1,130,1,124,7,116,12,116,17,131,1,100,1,133,2, - 25,0,125,8,124,8,160,18,161,0,144,1,115,14,116,14, - 100,13,124,7,155,2,100,14,157,3,131,1,130,1,124,2, - 160,19,100,6,161,1,100,15,25,0,125,9,116,20,124,1, - 124,9,116,21,100,15,25,0,23,0,131,2,83,0,41,16, - 97,110,1,0,0,71,105,118,101,110,32,116,104,101,32,112, - 97,116,104,32,116,111,32,97,32,46,112,121,99,46,32,102, - 105,108,101,44,32,114,101,116,117,114,110,32,116,104,101,32, - 112,97,116,104,32,116,111,32,105,116,115,32,46,112,121,32, - 102,105,108,101,46,10,10,32,32,32,32,84,104,101,32,46, - 112,121,99,32,102,105,108,101,32,100,111,101,115,32,110,111, - 116,32,110,101,101,100,32,116,111,32,101,120,105,115,116,59, - 32,116,104,105,115,32,115,105,109,112,108,121,32,114,101,116, - 117,114,110,115,32,116,104,101,32,112,97,116,104,32,116,111, - 10,32,32,32,32,116,104,101,32,46,112,121,32,102,105,108, - 101,32,99,97,108,99,117,108,97,116,101,100,32,116,111,32, - 99,111,114,114,101,115,112,111,110,100,32,116,111,32,116,104, - 101,32,46,112,121,99,32,102,105,108,101,46,32,32,73,102, - 32,112,97,116,104,32,100,111,101,115,10,32,32,32,32,110, - 111,116,32,99,111,110,102,111,114,109,32,116,111,32,80,69, - 80,32,51,49,52,55,47,52,56,56,32,102,111,114,109,97, - 116,44,32,86,97,108,117,101,69,114,114,111,114,32,119,105, - 108,108,32,98,101,32,114,97,105,115,101,100,46,32,73,102, - 10,32,32,32,32,115,121,115,46,105,109,112,108,101,109,101, + 105,111,110,39,32,116,111,32,39,49,39,46,10,10,32,32, + 32,32,73,102,32,115,121,115,46,105,109,112,108,101,109,101, 110,116,97,116,105,111,110,46,99,97,99,104,101,95,116,97, 103,32,105,115,32,78,111,110,101,32,116,104,101,110,32,78, 111,116,73,109,112,108,101,109,101,110,116,101,100,69,114,114, 111,114,32,105,115,32,114,97,105,115,101,100,46,10,10,32, - 32,32,32,78,114,72,0,0,0,70,84,122,31,32,110,111, - 116,32,98,111,116,116,111,109,45,108,101,118,101,108,32,100, - 105,114,101,99,116,111,114,121,32,105,110,32,114,71,0,0, - 0,62,2,0,0,0,114,28,0,0,0,114,57,0,0,0, - 122,29,101,120,112,101,99,116,101,100,32,111,110,108,121,32, - 50,32,111,114,32,51,32,100,111,116,115,32,105,110,32,114, - 57,0,0,0,114,28,0,0,0,233,254,255,255,255,122,53, - 111,112,116,105,109,105,122,97,116,105,111,110,32,112,111,114, - 116,105,111,110,32,111,102,32,102,105,108,101,110,97,109,101, - 32,100,111,101,115,32,110,111,116,32,115,116,97,114,116,32, - 119,105,116,104,32,122,19,111,112,116,105,109,105,122,97,116, - 105,111,110,32,108,101,118,101,108,32,122,29,32,105,115,32, - 110,111,116,32,97,110,32,97,108,112,104,97,110,117,109,101, - 114,105,99,32,118,97,108,117,101,114,73,0,0,0,41,22, - 114,8,0,0,0,114,80,0,0,0,114,81,0,0,0,114, - 82,0,0,0,114,2,0,0,0,114,79,0,0,0,114,47, - 0,0,0,114,90,0,0,0,114,30,0,0,0,114,31,0, - 0,0,114,10,0,0,0,114,35,0,0,0,114,22,0,0, - 0,114,92,0,0,0,114,87,0,0,0,218,5,99,111,117, - 110,116,114,43,0,0,0,114,88,0,0,0,114,86,0,0, - 0,218,9,112,97,114,116,105,116,105,111,110,114,38,0,0, - 0,218,15,83,79,85,82,67,69,95,83,85,70,70,73,88, - 69,83,41,10,114,44,0,0,0,114,94,0,0,0,90,16, - 112,121,99,97,99,104,101,95,102,105,108,101,110,97,109,101, - 90,23,102,111,117,110,100,95,105,110,95,112,121,99,97,99, - 104,101,95,112,114,101,102,105,120,90,13,115,116,114,105,112, - 112,101,100,95,112,97,116,104,90,7,112,121,99,97,99,104, - 101,90,9,100,111,116,95,99,111,117,110,116,114,70,0,0, - 0,90,9,111,112,116,95,108,101,118,101,108,90,13,98,97, - 115,101,95,102,105,108,101,110,97,109,101,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,17,115,111,117,114, - 99,101,95,102,114,111,109,95,99,97,99,104,101,104,1,0, - 0,115,52,0,0,0,0,9,12,1,8,1,10,1,12,1, - 4,1,10,1,12,1,14,1,16,1,4,1,4,1,12,1, - 8,1,18,2,10,1,8,1,16,1,10,1,16,1,10,1, - 14,2,16,1,10,1,16,2,14,1,114,103,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, - 9,0,0,0,67,0,0,0,115,126,0,0,0,116,0,124, - 0,131,1,100,1,107,2,114,16,100,2,83,0,124,0,160, - 1,100,3,161,1,92,3,125,1,125,2,125,3,124,1,114, - 56,124,3,160,2,161,0,100,4,100,5,133,2,25,0,100, - 6,107,3,114,60,124,0,83,0,122,12,116,3,124,0,131, - 1,125,4,87,0,110,36,4,0,116,4,116,5,102,2,107, - 10,114,108,1,0,1,0,1,0,124,0,100,2,100,5,133, - 2,25,0,125,4,89,0,110,2,88,0,116,6,124,4,131, - 1,114,122,124,4,83,0,124,0,83,0,41,7,122,188,67, - 111,110,118,101,114,116,32,97,32,98,121,116,101,99,111,100, - 101,32,102,105,108,101,32,112,97,116,104,32,116,111,32,97, - 32,115,111,117,114,99,101,32,112,97,116,104,32,40,105,102, - 32,112,111,115,115,105,98,108,101,41,46,10,10,32,32,32, - 32,84,104,105,115,32,102,117,110,99,116,105,111,110,32,101, - 120,105,115,116,115,32,112,117,114,101,108,121,32,102,111,114, - 32,98,97,99,107,119,97,114,100,115,45,99,111,109,112,97, - 116,105,98,105,108,105,116,121,32,102,111,114,10,32,32,32, - 32,80,121,73,109,112,111,114,116,95,69,120,101,99,67,111, - 100,101,77,111,100,117,108,101,87,105,116,104,70,105,108,101, - 110,97,109,101,115,40,41,32,105,110,32,116,104,101,32,67, - 32,65,80,73,46,10,10,32,32,32,32,114,73,0,0,0, - 78,114,71,0,0,0,233,253,255,255,255,233,255,255,255,255, - 90,2,112,121,41,7,114,22,0,0,0,114,41,0,0,0, - 218,5,108,111,119,101,114,114,103,0,0,0,114,82,0,0, - 0,114,87,0,0,0,114,54,0,0,0,41,5,218,13,98, - 121,116,101,99,111,100,101,95,112,97,116,104,114,96,0,0, - 0,114,45,0,0,0,90,9,101,120,116,101,110,115,105,111, - 110,218,11,115,111,117,114,99,101,95,112,97,116,104,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,15,95, - 103,101,116,95,115,111,117,114,99,101,102,105,108,101,144,1, - 0,0,115,20,0,0,0,0,7,12,1,4,1,16,1,24, - 1,4,1,2,1,12,1,18,1,18,1,114,109,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,8,0,0,0,67,0,0,0,115,74,0,0,0,124,0, - 160,0,116,1,116,2,131,1,161,1,114,48,122,10,116,3, - 124,0,131,1,87,0,83,0,4,0,116,4,107,10,114,44, - 1,0,1,0,1,0,89,0,113,70,88,0,110,22,124,0, - 160,0,116,1,116,5,131,1,161,1,114,66,124,0,83,0, - 100,0,83,0,100,0,83,0,169,1,78,41,6,218,8,101, - 110,100,115,119,105,116,104,218,5,116,117,112,108,101,114,102, - 0,0,0,114,98,0,0,0,114,82,0,0,0,114,89,0, - 0,0,41,1,114,97,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,11,95,103,101,116,95,99, - 97,99,104,101,100,163,1,0,0,115,16,0,0,0,0,1, - 14,1,2,1,10,1,14,1,8,1,14,1,4,2,114,113, - 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,52,0,0, - 0,122,14,116,0,124,0,131,1,106,1,125,1,87,0,110, - 24,4,0,116,2,107,10,114,38,1,0,1,0,1,0,100, - 1,125,1,89,0,110,2,88,0,124,1,100,2,79,0,125, - 1,124,1,83,0,41,3,122,51,67,97,108,99,117,108,97, - 116,101,32,116,104,101,32,109,111,100,101,32,112,101,114,109, - 105,115,115,105,111,110,115,32,102,111,114,32,97,32,98,121, - 116,101,99,111,100,101,32,102,105,108,101,46,114,60,0,0, - 0,233,128,0,0,0,41,3,114,49,0,0,0,114,51,0, - 0,0,114,50,0,0,0,41,2,114,44,0,0,0,114,52, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,10,95,99,97,108,99,95,109,111,100,101,175,1, - 0,0,115,12,0,0,0,0,2,2,1,14,1,14,1,10, - 3,8,1,114,115,0,0,0,99,1,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,8,0,0,0,3,0,0, - 0,115,68,0,0,0,100,6,135,0,102,1,100,2,100,3, - 132,9,125,1,122,10,116,0,106,1,125,2,87,0,110,28, - 4,0,116,2,107,10,114,52,1,0,1,0,1,0,100,4, - 100,5,132,0,125,2,89,0,110,2,88,0,124,2,124,1, - 136,0,131,2,1,0,124,1,83,0,41,7,122,252,68,101, - 99,111,114,97,116,111,114,32,116,111,32,118,101,114,105,102, - 121,32,116,104,97,116,32,116,104,101,32,109,111,100,117,108, - 101,32,98,101,105,110,103,32,114,101,113,117,101,115,116,101, - 100,32,109,97,116,99,104,101,115,32,116,104,101,32,111,110, - 101,32,116,104,101,10,32,32,32,32,108,111,97,100,101,114, - 32,99,97,110,32,104,97,110,100,108,101,46,10,10,32,32, - 32,32,84,104,101,32,102,105,114,115,116,32,97,114,103,117, - 109,101,110,116,32,40,115,101,108,102,41,32,109,117,115,116, - 32,100,101,102,105,110,101,32,95,110,97,109,101,32,119,104, - 105,99,104,32,116,104,101,32,115,101,99,111,110,100,32,97, - 114,103,117,109,101,110,116,32,105,115,10,32,32,32,32,99, - 111,109,112,97,114,101,100,32,97,103,97,105,110,115,116,46, - 32,73,102,32,116,104,101,32,99,111,109,112,97,114,105,115, - 111,110,32,102,97,105,108,115,32,116,104,101,110,32,73,109, - 112,111,114,116,69,114,114,111,114,32,105,115,32,114,97,105, - 115,101,100,46,10,10,32,32,32,32,78,99,2,0,0,0, - 0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0, - 31,0,0,0,115,66,0,0,0,124,1,100,0,107,8,114, - 16,124,0,106,0,125,1,110,32,124,0,106,0,124,1,107, - 3,114,48,116,1,100,1,124,0,106,0,124,1,102,2,22, - 0,124,1,100,2,141,2,130,1,136,0,124,0,124,1,102, - 2,124,2,158,2,124,3,142,1,83,0,41,3,78,122,30, - 108,111,97,100,101,114,32,102,111,114,32,37,115,32,99,97, - 110,110,111,116,32,104,97,110,100,108,101,32,37,115,169,1, - 218,4,110,97,109,101,41,2,114,117,0,0,0,218,11,73, - 109,112,111,114,116,69,114,114,111,114,41,4,218,4,115,101, - 108,102,114,117,0,0,0,218,4,97,114,103,115,90,6,107, - 119,97,114,103,115,169,1,218,6,109,101,116,104,111,100,114, - 3,0,0,0,114,6,0,0,0,218,19,95,99,104,101,99, - 107,95,110,97,109,101,95,119,114,97,112,112,101,114,195,1, - 0,0,115,18,0,0,0,0,1,8,1,8,1,10,1,4, - 1,8,255,2,1,2,255,6,2,122,40,95,99,104,101,99, - 107,95,110,97,109,101,46,60,108,111,99,97,108,115,62,46, - 95,99,104,101,99,107,95,110,97,109,101,95,119,114,97,112, - 112,101,114,99,2,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,7,0,0,0,83,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,0,83,0,41,2,78,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,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,114,67,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,5,95,119,114,97, - 112,206,1,0,0,115,8,0,0,0,0,1,8,1,10,1, - 20,1,122,26,95,99,104,101,99,107,95,110,97,109,101,46, - 60,108,111,99,97,108,115,62,46,95,119,114,97,112,41,1, - 78,41,3,218,10,95,98,111,111,116,115,116,114,97,112,114, - 133,0,0,0,218,9,78,97,109,101,69,114,114,111,114,41, - 3,114,122,0,0,0,114,123,0,0,0,114,133,0,0,0, - 114,3,0,0,0,114,121,0,0,0,114,6,0,0,0,218, - 11,95,99,104,101,99,107,95,110,97,109,101,187,1,0,0, - 115,14,0,0,0,0,8,14,7,2,1,10,1,14,2,14, - 5,10,1,114,136,0,0,0,99,2,0,0,0,0,0,0, - 0,0,0,0,0,5,0,0,0,6,0,0,0,67,0,0, - 0,115,60,0,0,0,124,0,160,0,124,1,161,1,92,2, - 125,2,125,3,124,2,100,1,107,8,114,56,116,1,124,3, - 131,1,114,56,100,2,125,4,116,2,160,3,124,4,160,4, - 124,3,100,3,25,0,161,1,116,5,161,2,1,0,124,2, - 83,0,41,4,122,155,84,114,121,32,116,111,32,102,105,110, - 100,32,97,32,108,111,97,100,101,114,32,102,111,114,32,116, - 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, - 117,108,101,32,98,121,32,100,101,108,101,103,97,116,105,110, - 103,32,116,111,10,32,32,32,32,115,101,108,102,46,102,105, - 110,100,95,108,111,97,100,101,114,40,41,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,32,105,110,32,102, - 97,118,111,114,32,111,102,32,102,105,110,100,101,114,46,102, - 105,110,100,95,115,112,101,99,40,41,46,10,10,32,32,32, - 32,78,122,44,78,111,116,32,105,109,112,111,114,116,105,110, - 103,32,100,105,114,101,99,116,111,114,121,32,123,125,58,32, - 109,105,115,115,105,110,103,32,95,95,105,110,105,116,95,95, - 114,73,0,0,0,41,6,218,11,102,105,110,100,95,108,111, - 97,100,101,114,114,22,0,0,0,114,75,0,0,0,114,76, - 0,0,0,114,62,0,0,0,218,13,73,109,112,111,114,116, - 87,97,114,110,105,110,103,41,5,114,119,0,0,0,218,8, - 102,117,108,108,110,97,109,101,218,6,108,111,97,100,101,114, - 218,8,112,111,114,116,105,111,110,115,218,3,109,115,103,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,17, - 95,102,105,110,100,95,109,111,100,117,108,101,95,115,104,105, - 109,215,1,0,0,115,10,0,0,0,0,10,14,1,16,1, - 4,1,22,1,114,143,0,0,0,99,3,0,0,0,0,0, - 0,0,0,0,0,0,6,0,0,0,4,0,0,0,67,0, - 0,0,115,158,0,0,0,124,0,100,1,100,2,133,2,25, - 0,125,3,124,3,116,0,107,3,114,60,100,3,124,1,155, - 2,100,4,124,3,155,2,157,4,125,4,116,1,160,2,100, - 5,124,4,161,2,1,0,116,3,124,4,102,1,124,2,142, - 1,130,1,116,4,124,0,131,1,100,6,107,0,114,102,100, - 7,124,1,155,2,157,2,125,4,116,1,160,2,100,5,124, - 4,161,2,1,0,116,5,124,4,131,1,130,1,116,6,124, - 0,100,2,100,8,133,2,25,0,131,1,125,5,124,5,100, - 9,64,0,114,154,100,10,124,5,155,2,100,11,124,1,155, - 2,157,4,125,4,116,3,124,4,102,1,124,2,142,1,130, - 1,124,5,83,0,41,12,97,84,2,0,0,80,101,114,102, - 111,114,109,32,98,97,115,105,99,32,118,97,108,105,100,105, - 116,121,32,99,104,101,99,107,105,110,103,32,111,102,32,97, - 32,112,121,99,32,104,101,97,100,101,114,32,97,110,100,32, - 114,101,116,117,114,110,32,116,104,101,32,102,108,97,103,115, - 32,102,105,101,108,100,44,10,32,32,32,32,119,104,105,99, - 104,32,100,101,116,101,114,109,105,110,101,115,32,104,111,119, - 32,116,104,101,32,112,121,99,32,115,104,111,117,108,100,32, - 98,101,32,102,117,114,116,104,101,114,32,118,97,108,105,100, - 97,116,101,100,32,97,103,97,105,110,115,116,32,116,104,101, - 32,115,111,117,114,99,101,46,10,10,32,32,32,32,42,100, + 32,32,32,78,122,70,116,104,101,32,100,101,98,117,103,95, + 111,118,101,114,114,105,100,101,32,112,97,114,97,109,101,116, + 101,114,32,105,115,32,100,101,112,114,101,99,97,116,101,100, + 59,32,117,115,101,32,39,111,112,116,105,109,105,122,97,116, + 105,111,110,39,32,105,110,115,116,101,97,100,122,50,100,101, + 98,117,103,95,111,118,101,114,114,105,100,101,32,111,114,32, + 111,112,116,105,109,105,122,97,116,105,111,110,32,109,117,115, + 116,32,98,101,32,115,101,116,32,116,111,32,78,111,110,101, + 114,40,0,0,0,114,39,0,0,0,218,1,46,250,36,115, + 121,115,46,105,109,112,108,101,109,101,110,116,97,116,105,111, + 110,46,99,97,99,104,101,95,116,97,103,32,105,115,32,78, + 111,110,101,233,0,0,0,0,122,24,123,33,114,125,32,105, + 115,32,110,111,116,32,97,108,112,104,97,110,117,109,101,114, + 105,99,122,7,123,125,46,123,125,123,125,250,1,58,114,28, + 0,0,0,41,28,218,9,95,119,97,114,110,105,110,103,115, + 218,4,119,97,114,110,218,18,68,101,112,114,101,99,97,116, + 105,111,110,87,97,114,110,105,110,103,218,9,84,121,112,101, + 69,114,114,111,114,114,2,0,0,0,218,6,102,115,112,97, + 116,104,114,47,0,0,0,114,41,0,0,0,114,8,0,0, + 0,218,14,105,109,112,108,101,109,101,110,116,97,116,105,111, + 110,218,9,99,97,99,104,101,95,116,97,103,218,19,78,111, + 116,73,109,112,108,101,109,101,110,116,101,100,69,114,114,111, + 114,114,36,0,0,0,218,5,102,108,97,103,115,218,8,111, + 112,116,105,109,105,122,101,218,3,115,116,114,218,7,105,115, + 97,108,110,117,109,218,10,86,97,108,117,101,69,114,114,111, + 114,114,62,0,0,0,218,4,95,79,80,84,218,17,66,89, + 84,69,67,79,68,69,95,83,85,70,70,73,88,69,83,218, + 14,112,121,99,97,99,104,101,95,112,114,101,102,105,120,114, + 59,0,0,0,114,38,0,0,0,114,55,0,0,0,114,31, + 0,0,0,218,6,108,115,116,114,105,112,218,8,95,80,89, + 67,65,67,72,69,41,12,114,44,0,0,0,90,14,100,101, + 98,117,103,95,111,118,101,114,114,105,100,101,114,70,0,0, + 0,218,7,109,101,115,115,97,103,101,218,4,104,101,97,100, + 114,46,0,0,0,90,4,98,97,115,101,218,3,115,101,112, + 218,4,114,101,115,116,90,3,116,97,103,90,15,97,108,109, + 111,115,116,95,102,105,108,101,110,97,109,101,218,8,102,105, + 108,101,110,97,109,101,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,17,99,97,99,104,101,95,102,114,111, + 109,95,115,111,117,114,99,101,38,1,0,0,115,72,0,0, + 0,0,18,8,1,6,1,2,255,4,2,8,1,4,1,8, + 1,12,1,10,1,12,1,16,1,8,1,8,1,8,1,24, + 1,8,1,12,1,6,2,8,1,8,1,8,1,8,1,14, + 1,14,1,12,1,12,9,10,1,14,5,28,1,12,4,2, + 1,4,1,8,1,2,253,4,5,114,98,0,0,0,99,1, + 0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,5, + 0,0,0,67,0,0,0,115,46,1,0,0,116,0,106,1, + 106,2,100,1,107,8,114,20,116,3,100,2,131,1,130,1, + 116,4,160,5,124,0,161,1,125,0,116,6,124,0,131,1, + 92,2,125,1,125,2,100,3,125,3,116,0,106,7,100,1, + 107,9,114,102,116,0,106,7,160,8,116,9,161,1,125,4, + 124,1,160,10,124,4,116,11,23,0,161,1,114,102,124,1, + 116,12,124,4,131,1,100,1,133,2,25,0,125,1,100,4, + 125,3,124,3,115,144,116,6,124,1,131,1,92,2,125,1, + 125,5,124,5,116,13,107,3,114,144,116,14,116,13,155,0, + 100,5,124,0,155,2,157,3,131,1,130,1,124,2,160,15, + 100,6,161,1,125,6,124,6,100,7,107,7,114,178,116,14, + 100,8,124,2,155,2,157,2,131,1,130,1,110,92,124,6, + 100,9,107,2,144,1,114,14,124,2,160,16,100,6,100,10, + 161,2,100,11,25,0,125,7,124,7,160,10,116,17,161,1, + 115,228,116,14,100,12,116,17,155,2,157,2,131,1,130,1, + 124,7,116,12,116,17,131,1,100,1,133,2,25,0,125,8, + 124,8,160,18,161,0,144,1,115,14,116,14,100,13,124,7, + 155,2,100,14,157,3,131,1,130,1,124,2,160,19,100,6, + 161,1,100,15,25,0,125,9,116,20,124,1,124,9,116,21, + 100,15,25,0,23,0,131,2,83,0,41,16,97,110,1,0, + 0,71,105,118,101,110,32,116,104,101,32,112,97,116,104,32, + 116,111,32,97,32,46,112,121,99,46,32,102,105,108,101,44, + 32,114,101,116,117,114,110,32,116,104,101,32,112,97,116,104, + 32,116,111,32,105,116,115,32,46,112,121,32,102,105,108,101, + 46,10,10,32,32,32,32,84,104,101,32,46,112,121,99,32, + 102,105,108,101,32,100,111,101,115,32,110,111,116,32,110,101, + 101,100,32,116,111,32,101,120,105,115,116,59,32,116,104,105, + 115,32,115,105,109,112,108,121,32,114,101,116,117,114,110,115, + 32,116,104,101,32,112,97,116,104,32,116,111,10,32,32,32, + 32,116,104,101,32,46,112,121,32,102,105,108,101,32,99,97, + 108,99,117,108,97,116,101,100,32,116,111,32,99,111,114,114, + 101,115,112,111,110,100,32,116,111,32,116,104,101,32,46,112, + 121,99,32,102,105,108,101,46,32,32,73,102,32,112,97,116, + 104,32,100,111,101,115,10,32,32,32,32,110,111,116,32,99, + 111,110,102,111,114,109,32,116,111,32,80,69,80,32,51,49, + 52,55,47,52,56,56,32,102,111,114,109,97,116,44,32,86, + 97,108,117,101,69,114,114,111,114,32,119,105,108,108,32,98, + 101,32,114,97,105,115,101,100,46,32,73,102,10,32,32,32, + 32,115,121,115,46,105,109,112,108,101,109,101,110,116,97,116, + 105,111,110,46,99,97,99,104,101,95,116,97,103,32,105,115, + 32,78,111,110,101,32,116,104,101,110,32,78,111,116,73,109, + 112,108,101,109,101,110,116,101,100,69,114,114,111,114,32,105, + 115,32,114,97,105,115,101,100,46,10,10,32,32,32,32,78, + 114,72,0,0,0,70,84,122,31,32,110,111,116,32,98,111, + 116,116,111,109,45,108,101,118,101,108,32,100,105,114,101,99, + 116,111,114,121,32,105,110,32,114,71,0,0,0,62,2,0, + 0,0,114,28,0,0,0,114,57,0,0,0,122,29,101,120, + 112,101,99,116,101,100,32,111,110,108,121,32,50,32,111,114, + 32,51,32,100,111,116,115,32,105,110,32,114,57,0,0,0, + 114,28,0,0,0,233,254,255,255,255,122,53,111,112,116,105, + 109,105,122,97,116,105,111,110,32,112,111,114,116,105,111,110, + 32,111,102,32,102,105,108,101,110,97,109,101,32,100,111,101, + 115,32,110,111,116,32,115,116,97,114,116,32,119,105,116,104, + 32,122,19,111,112,116,105,109,105,122,97,116,105,111,110,32, + 108,101,118,101,108,32,122,29,32,105,115,32,110,111,116,32, + 97,110,32,97,108,112,104,97,110,117,109,101,114,105,99,32, + 118,97,108,117,101,114,73,0,0,0,41,22,114,8,0,0, + 0,114,80,0,0,0,114,81,0,0,0,114,82,0,0,0, + 114,2,0,0,0,114,79,0,0,0,114,47,0,0,0,114, + 90,0,0,0,114,30,0,0,0,114,31,0,0,0,114,10, + 0,0,0,114,35,0,0,0,114,22,0,0,0,114,92,0, + 0,0,114,87,0,0,0,218,5,99,111,117,110,116,114,43, + 0,0,0,114,88,0,0,0,114,86,0,0,0,218,9,112, + 97,114,116,105,116,105,111,110,114,38,0,0,0,218,15,83, + 79,85,82,67,69,95,83,85,70,70,73,88,69,83,41,10, + 114,44,0,0,0,114,94,0,0,0,90,16,112,121,99,97, + 99,104,101,95,102,105,108,101,110,97,109,101,90,23,102,111, + 117,110,100,95,105,110,95,112,121,99,97,99,104,101,95,112, + 114,101,102,105,120,90,13,115,116,114,105,112,112,101,100,95, + 112,97,116,104,90,7,112,121,99,97,99,104,101,90,9,100, + 111,116,95,99,111,117,110,116,114,70,0,0,0,90,9,111, + 112,116,95,108,101,118,101,108,90,13,98,97,115,101,95,102, + 105,108,101,110,97,109,101,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,218,17,115,111,117,114,99,101,95,102, + 114,111,109,95,99,97,99,104,101,109,1,0,0,115,52,0, + 0,0,0,9,12,1,8,1,10,1,12,1,4,1,10,1, + 12,1,14,1,16,1,4,1,4,1,12,1,8,1,18,2, + 10,1,8,1,16,1,10,1,16,1,10,1,14,2,16,1, + 10,1,16,2,14,1,114,103,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,9,0,0,0, + 67,0,0,0,115,126,0,0,0,116,0,124,0,131,1,100, + 1,107,2,114,16,100,2,83,0,124,0,160,1,100,3,161, + 1,92,3,125,1,125,2,125,3,124,1,114,56,124,3,160, + 2,161,0,100,4,100,5,133,2,25,0,100,6,107,3,114, + 60,124,0,83,0,122,12,116,3,124,0,131,1,125,4,87, + 0,110,36,4,0,116,4,116,5,102,2,107,10,114,108,1, + 0,1,0,1,0,124,0,100,2,100,5,133,2,25,0,125, + 4,89,0,110,2,88,0,116,6,124,4,131,1,114,122,124, + 4,83,0,124,0,83,0,41,7,122,188,67,111,110,118,101, + 114,116,32,97,32,98,121,116,101,99,111,100,101,32,102,105, + 108,101,32,112,97,116,104,32,116,111,32,97,32,115,111,117, + 114,99,101,32,112,97,116,104,32,40,105,102,32,112,111,115, + 115,105,98,108,101,41,46,10,10,32,32,32,32,84,104,105, + 115,32,102,117,110,99,116,105,111,110,32,101,120,105,115,116, + 115,32,112,117,114,101,108,121,32,102,111,114,32,98,97,99, + 107,119,97,114,100,115,45,99,111,109,112,97,116,105,98,105, + 108,105,116,121,32,102,111,114,10,32,32,32,32,80,121,73, + 109,112,111,114,116,95,69,120,101,99,67,111,100,101,77,111, + 100,117,108,101,87,105,116,104,70,105,108,101,110,97,109,101, + 115,40,41,32,105,110,32,116,104,101,32,67,32,65,80,73, + 46,10,10,32,32,32,32,114,73,0,0,0,78,114,71,0, + 0,0,233,253,255,255,255,233,255,255,255,255,90,2,112,121, + 41,7,114,22,0,0,0,114,41,0,0,0,218,5,108,111, + 119,101,114,114,103,0,0,0,114,82,0,0,0,114,87,0, + 0,0,114,54,0,0,0,41,5,218,13,98,121,116,101,99, + 111,100,101,95,112,97,116,104,114,96,0,0,0,114,45,0, + 0,0,90,9,101,120,116,101,110,115,105,111,110,218,11,115, + 111,117,114,99,101,95,112,97,116,104,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,15,95,103,101,116,95, + 115,111,117,114,99,101,102,105,108,101,149,1,0,0,115,20, + 0,0,0,0,7,12,1,4,1,16,1,24,1,4,1,2, + 1,12,1,18,1,18,1,114,109,0,0,0,99,1,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0, + 0,67,0,0,0,115,74,0,0,0,124,0,160,0,116,1, + 116,2,131,1,161,1,114,48,122,10,116,3,124,0,131,1, + 87,0,83,0,4,0,116,4,107,10,114,44,1,0,1,0, + 1,0,89,0,113,70,88,0,110,22,124,0,160,0,116,1, + 116,5,131,1,161,1,114,66,124,0,83,0,100,0,83,0, + 100,0,83,0,169,1,78,41,6,218,8,101,110,100,115,119, + 105,116,104,218,5,116,117,112,108,101,114,102,0,0,0,114, + 98,0,0,0,114,82,0,0,0,114,89,0,0,0,41,1, + 114,97,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,218,11,95,103,101,116,95,99,97,99,104,101, + 100,168,1,0,0,115,16,0,0,0,0,1,14,1,2,1, + 10,1,14,1,8,1,14,1,4,2,114,113,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,52,0,0,0,122,14,116, + 0,124,0,131,1,106,1,125,1,87,0,110,24,4,0,116, + 2,107,10,114,38,1,0,1,0,1,0,100,1,125,1,89, + 0,110,2,88,0,124,1,100,2,79,0,125,1,124,1,83, + 0,41,3,122,51,67,97,108,99,117,108,97,116,101,32,116, + 104,101,32,109,111,100,101,32,112,101,114,109,105,115,115,105, + 111,110,115,32,102,111,114,32,97,32,98,121,116,101,99,111, + 100,101,32,102,105,108,101,46,114,60,0,0,0,233,128,0, + 0,0,41,3,114,49,0,0,0,114,51,0,0,0,114,50, + 0,0,0,41,2,114,44,0,0,0,114,52,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,10, + 95,99,97,108,99,95,109,111,100,101,180,1,0,0,115,12, + 0,0,0,0,2,2,1,14,1,14,1,10,3,8,1,114, + 115,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,8,0,0,0,3,0,0,0,115,68,0, + 0,0,100,6,135,0,102,1,100,2,100,3,132,9,125,1, + 122,10,116,0,106,1,125,2,87,0,110,28,4,0,116,2, + 107,10,114,52,1,0,1,0,1,0,100,4,100,5,132,0, + 125,2,89,0,110,2,88,0,124,2,124,1,136,0,131,2, + 1,0,124,1,83,0,41,7,122,252,68,101,99,111,114,97, + 116,111,114,32,116,111,32,118,101,114,105,102,121,32,116,104, + 97,116,32,116,104,101,32,109,111,100,117,108,101,32,98,101, + 105,110,103,32,114,101,113,117,101,115,116,101,100,32,109,97, + 116,99,104,101,115,32,116,104,101,32,111,110,101,32,116,104, + 101,10,32,32,32,32,108,111,97,100,101,114,32,99,97,110, + 32,104,97,110,100,108,101,46,10,10,32,32,32,32,84,104, + 101,32,102,105,114,115,116,32,97,114,103,117,109,101,110,116, + 32,40,115,101,108,102,41,32,109,117,115,116,32,100,101,102, + 105,110,101,32,95,110,97,109,101,32,119,104,105,99,104,32, + 116,104,101,32,115,101,99,111,110,100,32,97,114,103,117,109, + 101,110,116,32,105,115,10,32,32,32,32,99,111,109,112,97, + 114,101,100,32,97,103,97,105,110,115,116,46,32,73,102,32, + 116,104,101,32,99,111,109,112,97,114,105,115,111,110,32,102, + 97,105,108,115,32,116,104,101,110,32,73,109,112,111,114,116, + 69,114,114,111,114,32,105,115,32,114,97,105,115,101,100,46, + 10,10,32,32,32,32,78,99,2,0,0,0,0,0,0,0, + 0,0,0,0,4,0,0,0,4,0,0,0,31,0,0,0, + 115,66,0,0,0,124,1,100,0,107,8,114,16,124,0,106, + 0,125,1,110,32,124,0,106,0,124,1,107,3,114,48,116, + 1,100,1,124,0,106,0,124,1,102,2,22,0,124,1,100, + 2,141,2,130,1,136,0,124,0,124,1,102,2,124,2,158, + 2,124,3,142,1,83,0,41,3,78,122,30,108,111,97,100, + 101,114,32,102,111,114,32,37,115,32,99,97,110,110,111,116, + 32,104,97,110,100,108,101,32,37,115,169,1,218,4,110,97, + 109,101,41,2,114,117,0,0,0,218,11,73,109,112,111,114, + 116,69,114,114,111,114,41,4,218,4,115,101,108,102,114,117, + 0,0,0,218,4,97,114,103,115,218,6,107,119,97,114,103, + 115,169,1,218,6,109,101,116,104,111,100,114,3,0,0,0, + 114,6,0,0,0,218,19,95,99,104,101,99,107,95,110,97, + 109,101,95,119,114,97,112,112,101,114,200,1,0,0,115,18, + 0,0,0,0,1,8,1,8,1,10,1,4,1,8,255,2, + 1,2,255,6,2,122,40,95,99,104,101,99,107,95,110,97, + 109,101,46,60,108,111,99,97,108,115,62,46,95,99,104,101, + 99,107,95,110,97,109,101,95,119,114,97,112,112,101,114,99, + 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 7,0,0,0,83,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,0,83,0,41,2,78,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,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,114,67,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,218,5,95,119,114,97,112,211,1,0, + 0,115,8,0,0,0,0,1,8,1,10,1,20,1,122,26, + 95,99,104,101,99,107,95,110,97,109,101,46,60,108,111,99, + 97,108,115,62,46,95,119,114,97,112,41,1,78,41,3,218, + 10,95,98,111,111,116,115,116,114,97,112,114,134,0,0,0, + 218,9,78,97,109,101,69,114,114,111,114,41,3,114,123,0, + 0,0,114,124,0,0,0,114,134,0,0,0,114,3,0,0, + 0,114,122,0,0,0,114,6,0,0,0,218,11,95,99,104, + 101,99,107,95,110,97,109,101,192,1,0,0,115,14,0,0, + 0,0,8,14,7,2,1,10,1,14,2,14,5,10,1,114, + 137,0,0,0,99,2,0,0,0,0,0,0,0,0,0,0, + 0,5,0,0,0,6,0,0,0,67,0,0,0,115,60,0, + 0,0,124,0,160,0,124,1,161,1,92,2,125,2,125,3, + 124,2,100,1,107,8,114,56,116,1,124,3,131,1,114,56, + 100,2,125,4,116,2,160,3,124,4,160,4,124,3,100,3, + 25,0,161,1,116,5,161,2,1,0,124,2,83,0,41,4, + 122,155,84,114,121,32,116,111,32,102,105,110,100,32,97,32, + 108,111,97,100,101,114,32,102,111,114,32,116,104,101,32,115, + 112,101,99,105,102,105,101,100,32,109,111,100,117,108,101,32, + 98,121,32,100,101,108,101,103,97,116,105,110,103,32,116,111, + 10,32,32,32,32,115,101,108,102,46,102,105,110,100,95,108, + 111,97,100,101,114,40,41,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,32,105,110,32,102,97,118,111,114, + 32,111,102,32,102,105,110,100,101,114,46,102,105,110,100,95, + 115,112,101,99,40,41,46,10,10,32,32,32,32,78,122,44, + 78,111,116,32,105,109,112,111,114,116,105,110,103,32,100,105, + 114,101,99,116,111,114,121,32,123,125,58,32,109,105,115,115, + 105,110,103,32,95,95,105,110,105,116,95,95,114,73,0,0, + 0,41,6,218,11,102,105,110,100,95,108,111,97,100,101,114, + 114,22,0,0,0,114,75,0,0,0,114,76,0,0,0,114, + 62,0,0,0,218,13,73,109,112,111,114,116,87,97,114,110, + 105,110,103,41,5,114,119,0,0,0,218,8,102,117,108,108, + 110,97,109,101,218,6,108,111,97,100,101,114,218,8,112,111, + 114,116,105,111,110,115,218,3,109,115,103,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,17,95,102,105,110, + 100,95,109,111,100,117,108,101,95,115,104,105,109,220,1,0, + 0,115,10,0,0,0,0,10,14,1,16,1,4,1,22,1, + 114,144,0,0,0,99,3,0,0,0,0,0,0,0,0,0, + 0,0,6,0,0,0,4,0,0,0,67,0,0,0,115,158, + 0,0,0,124,0,100,1,100,2,133,2,25,0,125,3,124, + 3,116,0,107,3,114,60,100,3,124,1,155,2,100,4,124, + 3,155,2,157,4,125,4,116,1,160,2,100,5,124,4,161, + 2,1,0,116,3,124,4,102,1,124,2,142,1,130,1,116, + 4,124,0,131,1,100,6,107,0,114,102,100,7,124,1,155, + 2,157,2,125,4,116,1,160,2,100,5,124,4,161,2,1, + 0,116,5,124,4,131,1,130,1,116,6,124,0,100,2,100, + 8,133,2,25,0,131,1,125,5,124,5,100,9,64,0,114, + 154,100,10,124,5,155,2,100,11,124,1,155,2,157,4,125, + 4,116,3,124,4,102,1,124,2,142,1,130,1,124,5,83, + 0,41,12,97,84,2,0,0,80,101,114,102,111,114,109,32, + 98,97,115,105,99,32,118,97,108,105,100,105,116,121,32,99, + 104,101,99,107,105,110,103,32,111,102,32,97,32,112,121,99, + 32,104,101,97,100,101,114,32,97,110,100,32,114,101,116,117, + 114,110,32,116,104,101,32,102,108,97,103,115,32,102,105,101, + 108,100,44,10,32,32,32,32,119,104,105,99,104,32,100,101, + 116,101,114,109,105,110,101,115,32,104,111,119,32,116,104,101, + 32,112,121,99,32,115,104,111,117,108,100,32,98,101,32,102, + 117,114,116,104,101,114,32,118,97,108,105,100,97,116,101,100, + 32,97,103,97,105,110,115,116,32,116,104,101,32,115,111,117, + 114,99,101,46,10,10,32,32,32,32,42,100,97,116,97,42, + 32,105,115,32,116,104,101,32,99,111,110,116,101,110,116,115, + 32,111,102,32,116,104,101,32,112,121,99,32,102,105,108,101, + 46,32,40,79,110,108,121,32,116,104,101,32,102,105,114,115, + 116,32,49,54,32,98,121,116,101,115,32,97,114,101,10,32, + 32,32,32,114,101,113,117,105,114,101,100,44,32,116,104,111, + 117,103,104,46,41,10,10,32,32,32,32,42,110,97,109,101, + 42,32,105,115,32,116,104,101,32,110,97,109,101,32,111,102, + 32,116,104,101,32,109,111,100,117,108,101,32,98,101,105,110, + 103,32,105,109,112,111,114,116,101,100,46,32,73,116,32,105, + 115,32,117,115,101,100,32,102,111,114,32,108,111,103,103,105, + 110,103,46,10,10,32,32,32,32,42,101,120,99,95,100,101, + 116,97,105,108,115,42,32,105,115,32,97,32,100,105,99,116, + 105,111,110,97,114,121,32,112,97,115,115,101,100,32,116,111, + 32,73,109,112,111,114,116,69,114,114,111,114,32,105,102,32, + 105,116,32,114,97,105,115,101,100,32,102,111,114,10,32,32, + 32,32,105,109,112,114,111,118,101,100,32,100,101,98,117,103, + 103,105,110,103,46,10,10,32,32,32,32,73,109,112,111,114, + 116,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, + 32,119,104,101,110,32,116,104,101,32,109,97,103,105,99,32, + 110,117,109,98,101,114,32,105,115,32,105,110,99,111,114,114, + 101,99,116,32,111,114,32,119,104,101,110,32,116,104,101,32, + 102,108,97,103,115,10,32,32,32,32,102,105,101,108,100,32, + 105,115,32,105,110,118,97,108,105,100,46,32,69,79,70,69, + 114,114,111,114,32,105,115,32,114,97,105,115,101,100,32,119, + 104,101,110,32,116,104,101,32,100,97,116,97,32,105,115,32, + 102,111,117,110,100,32,116,111,32,98,101,32,116,114,117,110, + 99,97,116,101,100,46,10,10,32,32,32,32,78,114,15,0, + 0,0,122,20,98,97,100,32,109,97,103,105,99,32,110,117, + 109,98,101,114,32,105,110,32,122,2,58,32,250,2,123,125, + 233,16,0,0,0,122,40,114,101,97,99,104,101,100,32,69, + 79,70,32,119,104,105,108,101,32,114,101,97,100,105,110,103, + 32,112,121,99,32,104,101,97,100,101,114,32,111,102,32,233, + 8,0,0,0,233,252,255,255,255,122,14,105,110,118,97,108, + 105,100,32,102,108,97,103,115,32,122,4,32,105,110,32,41, + 7,218,12,77,65,71,73,67,95,78,85,77,66,69,82,114, + 135,0,0,0,218,16,95,118,101,114,98,111,115,101,95,109, + 101,115,115,97,103,101,114,118,0,0,0,114,22,0,0,0, + 218,8,69,79,70,69,114,114,111,114,114,27,0,0,0,41, + 6,114,26,0,0,0,114,117,0,0,0,218,11,101,120,99, + 95,100,101,116,97,105,108,115,90,5,109,97,103,105,99,114, + 93,0,0,0,114,83,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,13,95,99,108,97,115,115, + 105,102,121,95,112,121,99,237,1,0,0,115,28,0,0,0, + 0,16,12,1,8,1,16,1,12,1,12,1,12,1,10,1, + 12,1,8,1,16,2,8,1,16,1,12,1,114,153,0,0, + 0,99,5,0,0,0,0,0,0,0,0,0,0,0,6,0, + 0,0,4,0,0,0,67,0,0,0,115,112,0,0,0,116, + 0,124,0,100,1,100,2,133,2,25,0,131,1,124,1,100, + 3,64,0,107,3,114,58,100,4,124,3,155,2,157,2,125, + 5,116,1,160,2,100,5,124,5,161,2,1,0,116,3,124, + 5,102,1,124,4,142,1,130,1,124,2,100,6,107,9,114, + 108,116,0,124,0,100,2,100,7,133,2,25,0,131,1,124, + 2,100,3,64,0,107,3,114,108,116,3,100,4,124,3,155, + 2,157,2,102,1,124,4,142,1,130,1,100,6,83,0,41, + 8,97,7,2,0,0,86,97,108,105,100,97,116,101,32,97, + 32,112,121,99,32,97,103,97,105,110,115,116,32,116,104,101, + 32,115,111,117,114,99,101,32,108,97,115,116,45,109,111,100, + 105,102,105,101,100,32,116,105,109,101,46,10,10,32,32,32, + 32,42,100,97,116,97,42,32,105,115,32,116,104,101,32,99, + 111,110,116,101,110,116,115,32,111,102,32,116,104,101,32,112, + 121,99,32,102,105,108,101,46,32,40,79,110,108,121,32,116, + 104,101,32,102,105,114,115,116,32,49,54,32,98,121,116,101, + 115,32,97,114,101,10,32,32,32,32,114,101,113,117,105,114, + 101,100,46,41,10,10,32,32,32,32,42,115,111,117,114,99, + 101,95,109,116,105,109,101,42,32,105,115,32,116,104,101,32, + 108,97,115,116,32,109,111,100,105,102,105,101,100,32,116,105, + 109,101,115,116,97,109,112,32,111,102,32,116,104,101,32,115, + 111,117,114,99,101,32,102,105,108,101,46,10,10,32,32,32, + 32,42,115,111,117,114,99,101,95,115,105,122,101,42,32,105, + 115,32,78,111,110,101,32,111,114,32,116,104,101,32,115,105, + 122,101,32,111,102,32,116,104,101,32,115,111,117,114,99,101, + 32,102,105,108,101,32,105,110,32,98,121,116,101,115,46,10, + 10,32,32,32,32,42,110,97,109,101,42,32,105,115,32,116, + 104,101,32,110,97,109,101,32,111,102,32,116,104,101,32,109, + 111,100,117,108,101,32,98,101,105,110,103,32,105,109,112,111, + 114,116,101,100,46,32,73,116,32,105,115,32,117,115,101,100, + 32,102,111,114,32,108,111,103,103,105,110,103,46,10,10,32, + 32,32,32,42,101,120,99,95,100,101,116,97,105,108,115,42, + 32,105,115,32,97,32,100,105,99,116,105,111,110,97,114,121, + 32,112,97,115,115,101,100,32,116,111,32,73,109,112,111,114, + 116,69,114,114,111,114,32,105,102,32,105,116,32,114,97,105, + 115,101,100,32,102,111,114,10,32,32,32,32,105,109,112,114, + 111,118,101,100,32,100,101,98,117,103,103,105,110,103,46,10, + 10,32,32,32,32,65,110,32,73,109,112,111,114,116,69,114, + 114,111,114,32,105,115,32,114,97,105,115,101,100,32,105,102, + 32,116,104,101,32,98,121,116,101,99,111,100,101,32,105,115, + 32,115,116,97,108,101,46,10,10,32,32,32,32,114,147,0, + 0,0,233,12,0,0,0,114,14,0,0,0,122,22,98,121, + 116,101,99,111,100,101,32,105,115,32,115,116,97,108,101,32, + 102,111,114,32,114,145,0,0,0,78,114,146,0,0,0,41, + 4,114,27,0,0,0,114,135,0,0,0,114,150,0,0,0, + 114,118,0,0,0,41,6,114,26,0,0,0,218,12,115,111, + 117,114,99,101,95,109,116,105,109,101,218,11,115,111,117,114, + 99,101,95,115,105,122,101,114,117,0,0,0,114,152,0,0, + 0,114,93,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,23,95,118,97,108,105,100,97,116,101, + 95,116,105,109,101,115,116,97,109,112,95,112,121,99,14,2, + 0,0,115,16,0,0,0,0,19,24,1,10,1,12,1,12, + 1,8,1,22,255,2,2,114,157,0,0,0,99,4,0,0, + 0,0,0,0,0,0,0,0,0,4,0,0,0,3,0,0, + 0,67,0,0,0,115,38,0,0,0,124,0,100,1,100,2, + 133,2,25,0,124,1,107,3,114,34,116,0,100,3,124,2, + 155,2,157,2,102,1,124,3,142,1,130,1,100,4,83,0, + 41,5,97,243,1,0,0,86,97,108,105,100,97,116,101,32, + 97,32,104,97,115,104,45,98,97,115,101,100,32,112,121,99, + 32,98,121,32,99,104,101,99,107,105,110,103,32,116,104,101, + 32,114,101,97,108,32,115,111,117,114,99,101,32,104,97,115, + 104,32,97,103,97,105,110,115,116,32,116,104,101,32,111,110, + 101,32,105,110,10,32,32,32,32,116,104,101,32,112,121,99, + 32,104,101,97,100,101,114,46,10,10,32,32,32,32,42,100, 97,116,97,42,32,105,115,32,116,104,101,32,99,111,110,116, 101,110,116,115,32,111,102,32,116,104,101,32,112,121,99,32, 102,105,108,101,46,32,40,79,110,108,121,32,116,104,101,32, 102,105,114,115,116,32,49,54,32,98,121,116,101,115,32,97, - 114,101,10,32,32,32,32,114,101,113,117,105,114,101,100,44, - 32,116,104,111,117,103,104,46,41,10,10,32,32,32,32,42, - 110,97,109,101,42,32,105,115,32,116,104,101,32,110,97,109, - 101,32,111,102,32,116,104,101,32,109,111,100,117,108,101,32, - 98,101,105,110,103,32,105,109,112,111,114,116,101,100,46,32, - 73,116,32,105,115,32,117,115,101,100,32,102,111,114,32,108, - 111,103,103,105,110,103,46,10,10,32,32,32,32,42,101,120, - 99,95,100,101,116,97,105,108,115,42,32,105,115,32,97,32, - 100,105,99,116,105,111,110,97,114,121,32,112,97,115,115,101, - 100,32,116,111,32,73,109,112,111,114,116,69,114,114,111,114, - 32,105,102,32,105,116,32,114,97,105,115,101,100,32,102,111, - 114,10,32,32,32,32,105,109,112,114,111,118,101,100,32,100, - 101,98,117,103,103,105,110,103,46,10,10,32,32,32,32,73, - 109,112,111,114,116,69,114,114,111,114,32,105,115,32,114,97, - 105,115,101,100,32,119,104,101,110,32,116,104,101,32,109,97, - 103,105,99,32,110,117,109,98,101,114,32,105,115,32,105,110, - 99,111,114,114,101,99,116,32,111,114,32,119,104,101,110,32, - 116,104,101,32,102,108,97,103,115,10,32,32,32,32,102,105, - 101,108,100,32,105,115,32,105,110,118,97,108,105,100,46,32, - 69,79,70,69,114,114,111,114,32,105,115,32,114,97,105,115, - 101,100,32,119,104,101,110,32,116,104,101,32,100,97,116,97, - 32,105,115,32,102,111,117,110,100,32,116,111,32,98,101,32, - 116,114,117,110,99,97,116,101,100,46,10,10,32,32,32,32, - 78,114,15,0,0,0,122,20,98,97,100,32,109,97,103,105, - 99,32,110,117,109,98,101,114,32,105,110,32,122,2,58,32, - 250,2,123,125,233,16,0,0,0,122,40,114,101,97,99,104, - 101,100,32,69,79,70,32,119,104,105,108,101,32,114,101,97, - 100,105,110,103,32,112,121,99,32,104,101,97,100,101,114,32, - 111,102,32,233,8,0,0,0,233,252,255,255,255,122,14,105, - 110,118,97,108,105,100,32,102,108,97,103,115,32,122,4,32, - 105,110,32,41,7,218,12,77,65,71,73,67,95,78,85,77, - 66,69,82,114,134,0,0,0,218,16,95,118,101,114,98,111, - 115,101,95,109,101,115,115,97,103,101,114,118,0,0,0,114, - 22,0,0,0,218,8,69,79,70,69,114,114,111,114,114,27, - 0,0,0,41,6,114,26,0,0,0,114,117,0,0,0,218, - 11,101,120,99,95,100,101,116,97,105,108,115,90,5,109,97, - 103,105,99,114,93,0,0,0,114,83,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,13,95,99, - 108,97,115,115,105,102,121,95,112,121,99,232,1,0,0,115, - 28,0,0,0,0,16,12,1,8,1,16,1,12,1,12,1, - 12,1,10,1,12,1,8,1,16,2,8,1,16,1,12,1, - 114,152,0,0,0,99,5,0,0,0,0,0,0,0,0,0, - 0,0,6,0,0,0,4,0,0,0,67,0,0,0,115,112, - 0,0,0,116,0,124,0,100,1,100,2,133,2,25,0,131, - 1,124,1,100,3,64,0,107,3,114,58,100,4,124,3,155, - 2,157,2,125,5,116,1,160,2,100,5,124,5,161,2,1, - 0,116,3,124,5,102,1,124,4,142,1,130,1,124,2,100, - 6,107,9,114,108,116,0,124,0,100,2,100,7,133,2,25, - 0,131,1,124,2,100,3,64,0,107,3,114,108,116,3,100, - 4,124,3,155,2,157,2,102,1,124,4,142,1,130,1,100, - 6,83,0,41,8,97,7,2,0,0,86,97,108,105,100,97, - 116,101,32,97,32,112,121,99,32,97,103,97,105,110,115,116, - 32,116,104,101,32,115,111,117,114,99,101,32,108,97,115,116, - 45,109,111,100,105,102,105,101,100,32,116,105,109,101,46,10, - 10,32,32,32,32,42,100,97,116,97,42,32,105,115,32,116, - 104,101,32,99,111,110,116,101,110,116,115,32,111,102,32,116, - 104,101,32,112,121,99,32,102,105,108,101,46,32,40,79,110, - 108,121,32,116,104,101,32,102,105,114,115,116,32,49,54,32, - 98,121,116,101,115,32,97,114,101,10,32,32,32,32,114,101, - 113,117,105,114,101,100,46,41,10,10,32,32,32,32,42,115, - 111,117,114,99,101,95,109,116,105,109,101,42,32,105,115,32, - 116,104,101,32,108,97,115,116,32,109,111,100,105,102,105,101, - 100,32,116,105,109,101,115,116,97,109,112,32,111,102,32,116, - 104,101,32,115,111,117,114,99,101,32,102,105,108,101,46,10, - 10,32,32,32,32,42,115,111,117,114,99,101,95,115,105,122, - 101,42,32,105,115,32,78,111,110,101,32,111,114,32,116,104, - 101,32,115,105,122,101,32,111,102,32,116,104,101,32,115,111, - 117,114,99,101,32,102,105,108,101,32,105,110,32,98,121,116, - 101,115,46,10,10,32,32,32,32,42,110,97,109,101,42,32, - 105,115,32,116,104,101,32,110,97,109,101,32,111,102,32,116, - 104,101,32,109,111,100,117,108,101,32,98,101,105,110,103,32, - 105,109,112,111,114,116,101,100,46,32,73,116,32,105,115,32, - 117,115,101,100,32,102,111,114,32,108,111,103,103,105,110,103, - 46,10,10,32,32,32,32,42,101,120,99,95,100,101,116,97, - 105,108,115,42,32,105,115,32,97,32,100,105,99,116,105,111, - 110,97,114,121,32,112,97,115,115,101,100,32,116,111,32,73, - 109,112,111,114,116,69,114,114,111,114,32,105,102,32,105,116, - 32,114,97,105,115,101,100,32,102,111,114,10,32,32,32,32, - 105,109,112,114,111,118,101,100,32,100,101,98,117,103,103,105, - 110,103,46,10,10,32,32,32,32,65,110,32,73,109,112,111, - 114,116,69,114,114,111,114,32,105,115,32,114,97,105,115,101, - 100,32,105,102,32,116,104,101,32,98,121,116,101,99,111,100, - 101,32,105,115,32,115,116,97,108,101,46,10,10,32,32,32, - 32,114,146,0,0,0,233,12,0,0,0,114,14,0,0,0, - 122,22,98,121,116,101,99,111,100,101,32,105,115,32,115,116, - 97,108,101,32,102,111,114,32,114,144,0,0,0,78,114,145, - 0,0,0,41,4,114,27,0,0,0,114,134,0,0,0,114, - 149,0,0,0,114,118,0,0,0,41,6,114,26,0,0,0, - 218,12,115,111,117,114,99,101,95,109,116,105,109,101,218,11, - 115,111,117,114,99,101,95,115,105,122,101,114,117,0,0,0, - 114,151,0,0,0,114,93,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,23,95,118,97,108,105, - 100,97,116,101,95,116,105,109,101,115,116,97,109,112,95,112, - 121,99,9,2,0,0,115,16,0,0,0,0,19,24,1,10, - 1,12,1,12,1,8,1,22,255,2,2,114,156,0,0,0, - 99,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,3,0,0,0,67,0,0,0,115,38,0,0,0,124,0, - 100,1,100,2,133,2,25,0,124,1,107,3,114,34,116,0, - 100,3,124,2,155,2,157,2,102,1,124,3,142,1,130,1, - 100,4,83,0,41,5,97,243,1,0,0,86,97,108,105,100, - 97,116,101,32,97,32,104,97,115,104,45,98,97,115,101,100, - 32,112,121,99,32,98,121,32,99,104,101,99,107,105,110,103, - 32,116,104,101,32,114,101,97,108,32,115,111,117,114,99,101, - 32,104,97,115,104,32,97,103,97,105,110,115,116,32,116,104, - 101,32,111,110,101,32,105,110,10,32,32,32,32,116,104,101, - 32,112,121,99,32,104,101,97,100,101,114,46,10,10,32,32, - 32,32,42,100,97,116,97,42,32,105,115,32,116,104,101,32, - 99,111,110,116,101,110,116,115,32,111,102,32,116,104,101,32, - 112,121,99,32,102,105,108,101,46,32,40,79,110,108,121,32, - 116,104,101,32,102,105,114,115,116,32,49,54,32,98,121,116, - 101,115,32,97,114,101,10,32,32,32,32,114,101,113,117,105, - 114,101,100,46,41,10,10,32,32,32,32,42,115,111,117,114, - 99,101,95,104,97,115,104,42,32,105,115,32,116,104,101,32, - 105,109,112,111,114,116,108,105,98,46,117,116,105,108,46,115, - 111,117,114,99,101,95,104,97,115,104,40,41,32,111,102,32, - 116,104,101,32,115,111,117,114,99,101,32,102,105,108,101,46, - 10,10,32,32,32,32,42,110,97,109,101,42,32,105,115,32, - 116,104,101,32,110,97,109,101,32,111,102,32,116,104,101,32, - 109,111,100,117,108,101,32,98,101,105,110,103,32,105,109,112, - 111,114,116,101,100,46,32,73,116,32,105,115,32,117,115,101, - 100,32,102,111,114,32,108,111,103,103,105,110,103,46,10,10, - 32,32,32,32,42,101,120,99,95,100,101,116,97,105,108,115, - 42,32,105,115,32,97,32,100,105,99,116,105,111,110,97,114, - 121,32,112,97,115,115,101,100,32,116,111,32,73,109,112,111, - 114,116,69,114,114,111,114,32,105,102,32,105,116,32,114,97, - 105,115,101,100,32,102,111,114,10,32,32,32,32,105,109,112, - 114,111,118,101,100,32,100,101,98,117,103,103,105,110,103,46, - 10,10,32,32,32,32,65,110,32,73,109,112,111,114,116,69, - 114,114,111,114,32,105,115,32,114,97,105,115,101,100,32,105, - 102,32,116,104,101,32,98,121,116,101,99,111,100,101,32,105, - 115,32,115,116,97,108,101,46,10,10,32,32,32,32,114,146, - 0,0,0,114,145,0,0,0,122,46,104,97,115,104,32,105, - 110,32,98,121,116,101,99,111,100,101,32,100,111,101,115,110, - 39,116,32,109,97,116,99,104,32,104,97,115,104,32,111,102, - 32,115,111,117,114,99,101,32,78,41,1,114,118,0,0,0, - 41,4,114,26,0,0,0,218,11,115,111,117,114,99,101,95, - 104,97,115,104,114,117,0,0,0,114,151,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,18,95, - 118,97,108,105,100,97,116,101,95,104,97,115,104,95,112,121, - 99,37,2,0,0,115,12,0,0,0,0,17,16,1,2,1, - 8,255,2,2,2,254,114,158,0,0,0,99,4,0,0,0, - 0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, - 67,0,0,0,115,82,0,0,0,116,0,160,1,124,0,161, - 1,125,4,116,2,124,4,116,3,131,2,114,58,116,4,160, - 5,100,1,124,2,161,2,1,0,124,3,100,2,107,9,114, - 52,116,6,160,7,124,4,124,3,161,2,1,0,124,4,83, - 0,110,20,116,8,100,3,160,9,124,2,161,1,124,1,124, - 2,100,4,141,3,130,1,100,2,83,0,41,5,122,35,67, - 111,109,112,105,108,101,32,98,121,116,101,99,111,100,101,32, - 97,115,32,102,111,117,110,100,32,105,110,32,97,32,112,121, - 99,46,122,21,99,111,100,101,32,111,98,106,101,99,116,32, - 102,114,111,109,32,123,33,114,125,78,122,23,78,111,110,45, - 99,111,100,101,32,111,98,106,101,99,116,32,105,110,32,123, - 33,114,125,169,2,114,117,0,0,0,114,44,0,0,0,41, - 10,218,7,109,97,114,115,104,97,108,90,5,108,111,97,100, - 115,218,10,105,115,105,110,115,116,97,110,99,101,218,10,95, - 99,111,100,101,95,116,121,112,101,114,134,0,0,0,114,149, - 0,0,0,218,4,95,105,109,112,90,16,95,102,105,120,95, - 99,111,95,102,105,108,101,110,97,109,101,114,118,0,0,0, - 114,62,0,0,0,41,5,114,26,0,0,0,114,117,0,0, - 0,114,107,0,0,0,114,108,0,0,0,218,4,99,111,100, - 101,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 218,17,95,99,111,109,112,105,108,101,95,98,121,116,101,99, - 111,100,101,61,2,0,0,115,20,0,0,0,0,2,10,1, - 10,1,12,1,8,1,12,1,6,2,10,1,2,0,2,255, - 114,165,0,0,0,114,73,0,0,0,99,3,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,67, - 0,0,0,115,70,0,0,0,116,0,116,1,131,1,125,3, - 124,3,160,2,116,3,100,1,131,1,161,1,1,0,124,3, - 160,2,116,3,124,1,131,1,161,1,1,0,124,3,160,2, - 116,3,124,2,131,1,161,1,1,0,124,3,160,2,116,4, - 160,5,124,0,161,1,161,1,1,0,124,3,83,0,41,2, - 122,43,80,114,111,100,117,99,101,32,116,104,101,32,100,97, - 116,97,32,102,111,114,32,97,32,116,105,109,101,115,116,97, - 109,112,45,98,97,115,101,100,32,112,121,99,46,114,73,0, - 0,0,41,6,218,9,98,121,116,101,97,114,114,97,121,114, - 148,0,0,0,218,6,101,120,116,101,110,100,114,20,0,0, - 0,114,160,0,0,0,218,5,100,117,109,112,115,41,4,114, - 164,0,0,0,218,5,109,116,105,109,101,114,155,0,0,0, - 114,26,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,22,95,99,111,100,101,95,116,111,95,116, - 105,109,101,115,116,97,109,112,95,112,121,99,74,2,0,0, - 115,12,0,0,0,0,2,8,1,14,1,14,1,14,1,16, - 1,114,170,0,0,0,84,99,3,0,0,0,0,0,0,0, + 114,101,10,32,32,32,32,114,101,113,117,105,114,101,100,46, + 41,10,10,32,32,32,32,42,115,111,117,114,99,101,95,104, + 97,115,104,42,32,105,115,32,116,104,101,32,105,109,112,111, + 114,116,108,105,98,46,117,116,105,108,46,115,111,117,114,99, + 101,95,104,97,115,104,40,41,32,111,102,32,116,104,101,32, + 115,111,117,114,99,101,32,102,105,108,101,46,10,10,32,32, + 32,32,42,110,97,109,101,42,32,105,115,32,116,104,101,32, + 110,97,109,101,32,111,102,32,116,104,101,32,109,111,100,117, + 108,101,32,98,101,105,110,103,32,105,109,112,111,114,116,101, + 100,46,32,73,116,32,105,115,32,117,115,101,100,32,102,111, + 114,32,108,111,103,103,105,110,103,46,10,10,32,32,32,32, + 42,101,120,99,95,100,101,116,97,105,108,115,42,32,105,115, + 32,97,32,100,105,99,116,105,111,110,97,114,121,32,112,97, + 115,115,101,100,32,116,111,32,73,109,112,111,114,116,69,114, + 114,111,114,32,105,102,32,105,116,32,114,97,105,115,101,100, + 32,102,111,114,10,32,32,32,32,105,109,112,114,111,118,101, + 100,32,100,101,98,117,103,103,105,110,103,46,10,10,32,32, + 32,32,65,110,32,73,109,112,111,114,116,69,114,114,111,114, + 32,105,115,32,114,97,105,115,101,100,32,105,102,32,116,104, + 101,32,98,121,116,101,99,111,100,101,32,105,115,32,115,116, + 97,108,101,46,10,10,32,32,32,32,114,147,0,0,0,114, + 146,0,0,0,122,46,104,97,115,104,32,105,110,32,98,121, + 116,101,99,111,100,101,32,100,111,101,115,110,39,116,32,109, + 97,116,99,104,32,104,97,115,104,32,111,102,32,115,111,117, + 114,99,101,32,78,41,1,114,118,0,0,0,41,4,114,26, + 0,0,0,218,11,115,111,117,114,99,101,95,104,97,115,104, + 114,117,0,0,0,114,152,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,18,95,118,97,108,105, + 100,97,116,101,95,104,97,115,104,95,112,121,99,42,2,0, + 0,115,12,0,0,0,0,17,16,1,2,1,8,255,2,2, + 2,254,114,159,0,0,0,99,4,0,0,0,0,0,0,0, 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, - 115,80,0,0,0,116,0,116,1,131,1,125,3,100,1,124, - 2,100,1,62,0,66,0,125,4,124,3,160,2,116,3,124, - 4,131,1,161,1,1,0,116,4,124,1,131,1,100,2,107, - 2,115,50,116,5,130,1,124,3,160,2,124,1,161,1,1, - 0,124,3,160,2,116,6,160,7,124,0,161,1,161,1,1, - 0,124,3,83,0,41,3,122,38,80,114,111,100,117,99,101, - 32,116,104,101,32,100,97,116,97,32,102,111,114,32,97,32, - 104,97,115,104,45,98,97,115,101,100,32,112,121,99,46,114, - 39,0,0,0,114,146,0,0,0,41,8,114,166,0,0,0, - 114,148,0,0,0,114,167,0,0,0,114,20,0,0,0,114, - 22,0,0,0,114,23,0,0,0,114,160,0,0,0,114,168, - 0,0,0,41,5,114,164,0,0,0,114,157,0,0,0,90, - 7,99,104,101,99,107,101,100,114,26,0,0,0,114,83,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,17,95,99,111,100,101,95,116,111,95,104,97,115,104, - 95,112,121,99,84,2,0,0,115,14,0,0,0,0,2,8, - 1,12,1,14,1,16,1,10,1,16,1,114,171,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,5,0,0, - 0,6,0,0,0,67,0,0,0,115,62,0,0,0,100,1, - 100,2,108,0,125,1,116,1,160,2,124,0,161,1,106,3, - 125,2,124,1,160,4,124,2,161,1,125,3,116,1,160,5, - 100,2,100,3,161,2,125,4,124,4,160,6,124,0,160,6, - 124,3,100,1,25,0,161,1,161,1,83,0,41,4,122,121, - 68,101,99,111,100,101,32,98,121,116,101,115,32,114,101,112, - 114,101,115,101,110,116,105,110,103,32,115,111,117,114,99,101, - 32,99,111,100,101,32,97,110,100,32,114,101,116,117,114,110, - 32,116,104,101,32,115,116,114,105,110,103,46,10,10,32,32, - 32,32,85,110,105,118,101,114,115,97,108,32,110,101,119,108, - 105,110,101,32,115,117,112,112,111,114,116,32,105,115,32,117, - 115,101,100,32,105,110,32,116,104,101,32,100,101,99,111,100, - 105,110,103,46,10,32,32,32,32,114,73,0,0,0,78,84, - 41,7,218,8,116,111,107,101,110,105,122,101,114,64,0,0, - 0,90,7,66,121,116,101,115,73,79,90,8,114,101,97,100, - 108,105,110,101,90,15,100,101,116,101,99,116,95,101,110,99, - 111,100,105,110,103,90,25,73,110,99,114,101,109,101,110,116, - 97,108,78,101,119,108,105,110,101,68,101,99,111,100,101,114, - 218,6,100,101,99,111,100,101,41,5,218,12,115,111,117,114, - 99,101,95,98,121,116,101,115,114,172,0,0,0,90,21,115, - 111,117,114,99,101,95,98,121,116,101,115,95,114,101,97,100, - 108,105,110,101,218,8,101,110,99,111,100,105,110,103,90,15, - 110,101,119,108,105,110,101,95,100,101,99,111,100,101,114,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,13, - 100,101,99,111,100,101,95,115,111,117,114,99,101,95,2,0, - 0,115,10,0,0,0,0,5,8,1,12,1,10,1,12,1, - 114,176,0,0,0,169,2,114,140,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,99,2,0,0,0,0,0,0, - 0,2,0,0,0,9,0,0,0,8,0,0,0,67,0,0, - 0,115,16,1,0,0,124,1,100,1,107,8,114,60,100,2, - 125,1,116,0,124,2,100,3,131,2,114,70,122,14,124,2, - 160,1,124,0,161,1,125,1,87,0,113,70,4,0,116,2, - 107,10,114,56,1,0,1,0,1,0,89,0,113,70,88,0, - 110,10,116,3,160,4,124,1,161,1,125,1,116,5,106,6, - 124,0,124,2,124,1,100,4,141,3,125,4,100,5,124,4, - 95,7,124,2,100,1,107,8,114,154,116,8,131,0,68,0, - 93,42,92,2,125,5,125,6,124,1,160,9,116,10,124,6, - 131,1,161,1,114,106,124,5,124,0,124,1,131,2,125,2, - 124,2,124,4,95,11,1,0,113,154,113,106,100,1,83,0, - 124,3,116,12,107,8,114,220,116,0,124,2,100,6,131,2, - 114,226,122,14,124,2,160,13,124,0,161,1,125,7,87,0, - 110,20,4,0,116,2,107,10,114,206,1,0,1,0,1,0, - 89,0,113,226,88,0,124,7,114,226,103,0,124,4,95,14, - 110,6,124,3,124,4,95,14,124,4,106,14,103,0,107,2, - 144,1,114,12,124,1,144,1,114,12,116,15,124,1,131,1, - 100,7,25,0,125,8,124,4,106,14,160,16,124,8,161,1, - 1,0,124,4,83,0,41,8,97,61,1,0,0,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,97,32,102,105,108, - 101,32,108,111,99,97,116,105,111,110,46,10,10,32,32,32, - 32,84,111,32,105,110,100,105,99,97,116,101,32,116,104,97, - 116,32,116,104,101,32,109,111,100,117,108,101,32,105,115,32, - 97,32,112,97,99,107,97,103,101,44,32,115,101,116,10,32, - 32,32,32,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,32,116,111, - 32,97,32,108,105,115,116,32,111,102,32,100,105,114,101,99, - 116,111,114,121,32,112,97,116,104,115,46,32,32,65,110,10, - 32,32,32,32,101,109,112,116,121,32,108,105,115,116,32,105, - 115,32,115,117,102,102,105,99,105,101,110,116,44,32,116,104, - 111,117,103,104,32,105,116,115,32,110,111,116,32,111,116,104, - 101,114,119,105,115,101,32,117,115,101,102,117,108,32,116,111, - 32,116,104,101,10,32,32,32,32,105,109,112,111,114,116,32, - 115,121,115,116,101,109,46,10,10,32,32,32,32,84,104,101, - 32,108,111,97,100,101,114,32,109,117,115,116,32,116,97,107, - 101,32,97,32,115,112,101,99,32,97,115,32,105,116,115,32, - 111,110,108,121,32,95,95,105,110,105,116,95,95,40,41,32, - 97,114,103,46,10,10,32,32,32,32,78,122,9,60,117,110, - 107,110,111,119,110,62,218,12,103,101,116,95,102,105,108,101, - 110,97,109,101,169,1,218,6,111,114,105,103,105,110,84,218, - 10,105,115,95,112,97,99,107,97,103,101,114,73,0,0,0, - 41,17,114,128,0,0,0,114,179,0,0,0,114,118,0,0, - 0,114,2,0,0,0,114,79,0,0,0,114,134,0,0,0, - 218,10,77,111,100,117,108,101,83,112,101,99,90,13,95,115, - 101,116,95,102,105,108,101,97,116,116,114,218,27,95,103,101, - 116,95,115,117,112,112,111,114,116,101,100,95,102,105,108,101, - 95,108,111,97,100,101,114,115,114,111,0,0,0,114,112,0, - 0,0,114,140,0,0,0,218,9,95,80,79,80,85,76,65, - 84,69,114,182,0,0,0,114,178,0,0,0,114,47,0,0, - 0,218,6,97,112,112,101,110,100,41,9,114,117,0,0,0, - 90,8,108,111,99,97,116,105,111,110,114,140,0,0,0,114, - 178,0,0,0,218,4,115,112,101,99,218,12,108,111,97,100, - 101,114,95,99,108,97,115,115,218,8,115,117,102,102,105,120, - 101,115,114,182,0,0,0,90,7,100,105,114,110,97,109,101, - 114,3,0,0,0,114,3,0,0,0,114,6,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,112,2,0,0,115,62,0,0, - 0,0,12,8,4,4,1,10,2,2,1,14,1,14,1,8, - 2,10,8,16,1,6,3,8,1,14,1,14,1,10,1,6, - 1,6,2,4,3,8,2,10,1,2,1,14,1,14,1,6, - 2,4,1,8,2,6,1,12,1,6,1,12,1,12,2,114, - 190,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,86,0, - 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, - 90,4,100,3,90,5,100,4,90,6,101,7,100,5,100,6, - 132,0,131,1,90,8,101,7,100,7,100,8,132,0,131,1, - 90,9,101,7,100,9,100,9,102,2,100,10,100,11,132,1, - 131,1,90,10,101,7,100,9,102,1,100,12,100,13,132,1, - 131,1,90,11,100,9,83,0,41,14,218,21,87,105,110,100, - 111,119,115,82,101,103,105,115,116,114,121,70,105,110,100,101, - 114,122,62,77,101,116,97,32,112,97,116,104,32,102,105,110, - 100,101,114,32,102,111,114,32,109,111,100,117,108,101,115,32, - 100,101,99,108,97,114,101,100,32,105,110,32,116,104,101,32, - 87,105,110,100,111,119,115,32,114,101,103,105,115,116,114,121, - 46,122,59,83,111,102,116,119,97,114,101,92,80,121,116,104, - 111,110,92,80,121,116,104,111,110,67,111,114,101,92,123,115, - 121,115,95,118,101,114,115,105,111,110,125,92,77,111,100,117, - 108,101,115,92,123,102,117,108,108,110,97,109,101,125,122,65, - 83,111,102,116,119,97,114,101,92,80,121,116,104,111,110,92, - 80,121,116,104,111,110,67,111,114,101,92,123,115,121,115,95, - 118,101,114,115,105,111,110,125,92,77,111,100,117,108,101,115, - 92,123,102,117,108,108,110,97,109,101,125,92,68,101,98,117, - 103,70,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,8,0,0,0,67,0,0,0,115,56,0,0,0, - 122,16,116,0,160,1,116,0,106,2,124,1,161,2,87,0, - 83,0,4,0,116,3,107,10,114,50,1,0,1,0,1,0, - 116,0,160,1,116,0,106,4,124,1,161,2,6,0,89,0, - 83,0,88,0,100,0,83,0,114,110,0,0,0,41,5,218, - 7,95,119,105,110,114,101,103,90,7,79,112,101,110,75,101, - 121,90,17,72,75,69,89,95,67,85,82,82,69,78,84,95, - 85,83,69,82,114,50,0,0,0,90,18,72,75,69,89,95, - 76,79,67,65,76,95,77,65,67,72,73,78,69,41,2,218, - 3,99,108,115,114,5,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,14,95,111,112,101,110,95, - 114,101,103,105,115,116,114,121,192,2,0,0,115,8,0,0, - 0,0,2,2,1,16,1,14,1,122,36,87,105,110,100,111, - 119,115,82,101,103,105,115,116,114,121,70,105,110,100,101,114, - 46,95,111,112,101,110,95,114,101,103,105,115,116,114,121,99, - 2,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, - 9,0,0,0,67,0,0,0,115,118,0,0,0,124,0,106, - 0,114,14,124,0,106,1,125,2,110,6,124,0,106,2,125, - 2,124,2,106,3,124,1,100,1,116,4,106,5,100,0,100, - 2,133,2,25,0,22,0,100,3,141,2,125,3,122,38,124, - 0,160,6,124,3,161,1,143,18,125,4,116,7,160,8,124, - 4,100,4,161,2,125,5,87,0,53,0,81,0,82,0,88, - 0,87,0,110,26,4,0,116,9,107,10,114,112,1,0,1, - 0,1,0,89,0,100,0,83,0,89,0,110,2,88,0,124, + 115,80,0,0,0,116,0,160,1,124,0,161,1,125,4,116, + 2,124,4,116,3,131,2,114,56,116,4,160,5,100,1,124, + 2,161,2,1,0,124,3,100,2,107,9,114,52,116,6,160, + 7,124,4,124,3,161,2,1,0,124,4,83,0,116,8,100, + 3,160,9,124,2,161,1,124,1,124,2,100,4,141,3,130, + 1,100,2,83,0,41,5,122,35,67,111,109,112,105,108,101, + 32,98,121,116,101,99,111,100,101,32,97,115,32,102,111,117, + 110,100,32,105,110,32,97,32,112,121,99,46,122,21,99,111, + 100,101,32,111,98,106,101,99,116,32,102,114,111,109,32,123, + 33,114,125,78,122,23,78,111,110,45,99,111,100,101,32,111, + 98,106,101,99,116,32,105,110,32,123,33,114,125,169,2,114, + 117,0,0,0,114,44,0,0,0,41,10,218,7,109,97,114, + 115,104,97,108,90,5,108,111,97,100,115,218,10,105,115,105, + 110,115,116,97,110,99,101,218,10,95,99,111,100,101,95,116, + 121,112,101,114,135,0,0,0,114,150,0,0,0,218,4,95, + 105,109,112,90,16,95,102,105,120,95,99,111,95,102,105,108, + 101,110,97,109,101,114,118,0,0,0,114,62,0,0,0,41, + 5,114,26,0,0,0,114,117,0,0,0,114,107,0,0,0, + 114,108,0,0,0,218,4,99,111,100,101,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,17,95,99,111,109, + 112,105,108,101,95,98,121,116,101,99,111,100,101,66,2,0, + 0,115,20,0,0,0,0,2,10,1,10,1,12,1,8,1, + 12,1,4,2,10,1,2,0,2,255,114,166,0,0,0,114, + 73,0,0,0,99,3,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,5,0,0,0,67,0,0,0,115,70,0, + 0,0,116,0,116,1,131,1,125,3,124,3,160,2,116,3, + 100,1,131,1,161,1,1,0,124,3,160,2,116,3,124,1, + 131,1,161,1,1,0,124,3,160,2,116,3,124,2,131,1, + 161,1,1,0,124,3,160,2,116,4,160,5,124,0,161,1, + 161,1,1,0,124,3,83,0,41,2,122,43,80,114,111,100, + 117,99,101,32,116,104,101,32,100,97,116,97,32,102,111,114, + 32,97,32,116,105,109,101,115,116,97,109,112,45,98,97,115, + 101,100,32,112,121,99,46,114,73,0,0,0,41,6,218,9, + 98,121,116,101,97,114,114,97,121,114,149,0,0,0,218,6, + 101,120,116,101,110,100,114,20,0,0,0,114,161,0,0,0, + 218,5,100,117,109,112,115,41,4,114,165,0,0,0,218,5, + 109,116,105,109,101,114,156,0,0,0,114,26,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,22, + 95,99,111,100,101,95,116,111,95,116,105,109,101,115,116,97, + 109,112,95,112,121,99,79,2,0,0,115,12,0,0,0,0, + 2,8,1,14,1,14,1,14,1,16,1,114,171,0,0,0, + 84,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,80,0,0,0,116, + 0,116,1,131,1,125,3,100,1,124,2,100,1,62,0,66, + 0,125,4,124,3,160,2,116,3,124,4,131,1,161,1,1, + 0,116,4,124,1,131,1,100,2,107,2,115,50,116,5,130, + 1,124,3,160,2,124,1,161,1,1,0,124,3,160,2,116, + 6,160,7,124,0,161,1,161,1,1,0,124,3,83,0,41, + 3,122,38,80,114,111,100,117,99,101,32,116,104,101,32,100, + 97,116,97,32,102,111,114,32,97,32,104,97,115,104,45,98, + 97,115,101,100,32,112,121,99,46,114,39,0,0,0,114,147, + 0,0,0,41,8,114,167,0,0,0,114,149,0,0,0,114, + 168,0,0,0,114,20,0,0,0,114,22,0,0,0,114,23, + 0,0,0,114,161,0,0,0,114,169,0,0,0,41,5,114, + 165,0,0,0,114,158,0,0,0,90,7,99,104,101,99,107, + 101,100,114,26,0,0,0,114,83,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,17,95,99,111, + 100,101,95,116,111,95,104,97,115,104,95,112,121,99,89,2, + 0,0,115,14,0,0,0,0,2,8,1,12,1,14,1,16, + 1,10,1,16,1,114,172,0,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,67, + 0,0,0,115,62,0,0,0,100,1,100,2,108,0,125,1, + 116,1,160,2,124,0,161,1,106,3,125,2,124,1,160,4, + 124,2,161,1,125,3,116,1,160,5,100,2,100,3,161,2, + 125,4,124,4,160,6,124,0,160,6,124,3,100,1,25,0, + 161,1,161,1,83,0,41,4,122,121,68,101,99,111,100,101, + 32,98,121,116,101,115,32,114,101,112,114,101,115,101,110,116, + 105,110,103,32,115,111,117,114,99,101,32,99,111,100,101,32, + 97,110,100,32,114,101,116,117,114,110,32,116,104,101,32,115, + 116,114,105,110,103,46,10,10,32,32,32,32,85,110,105,118, + 101,114,115,97,108,32,110,101,119,108,105,110,101,32,115,117, + 112,112,111,114,116,32,105,115,32,117,115,101,100,32,105,110, + 32,116,104,101,32,100,101,99,111,100,105,110,103,46,10,32, + 32,32,32,114,73,0,0,0,78,84,41,7,218,8,116,111, + 107,101,110,105,122,101,114,64,0,0,0,90,7,66,121,116, + 101,115,73,79,90,8,114,101,97,100,108,105,110,101,90,15, + 100,101,116,101,99,116,95,101,110,99,111,100,105,110,103,90, + 25,73,110,99,114,101,109,101,110,116,97,108,78,101,119,108, + 105,110,101,68,101,99,111,100,101,114,218,6,100,101,99,111, + 100,101,41,5,218,12,115,111,117,114,99,101,95,98,121,116, + 101,115,114,173,0,0,0,90,21,115,111,117,114,99,101,95, + 98,121,116,101,115,95,114,101,97,100,108,105,110,101,218,8, + 101,110,99,111,100,105,110,103,90,15,110,101,119,108,105,110, + 101,95,100,101,99,111,100,101,114,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,13,100,101,99,111,100,101, + 95,115,111,117,114,99,101,100,2,0,0,115,10,0,0,0, + 0,5,8,1,12,1,10,1,12,1,114,177,0,0,0,169, + 2,114,141,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,99,2,0,0,0,0,0,0,0,2,0,0,0,9, + 0,0,0,8,0,0,0,67,0,0,0,115,16,1,0,0, + 124,1,100,1,107,8,114,60,100,2,125,1,116,0,124,2, + 100,3,131,2,114,70,122,14,124,2,160,1,124,0,161,1, + 125,1,87,0,113,70,4,0,116,2,107,10,114,56,1,0, + 1,0,1,0,89,0,113,70,88,0,110,10,116,3,160,4, + 124,1,161,1,125,1,116,5,106,6,124,0,124,2,124,1, + 100,4,141,3,125,4,100,5,124,4,95,7,124,2,100,1, + 107,8,114,154,116,8,131,0,68,0,93,42,92,2,125,5, + 125,6,124,1,160,9,116,10,124,6,131,1,161,1,114,106, + 124,5,124,0,124,1,131,2,125,2,124,2,124,4,95,11, + 1,0,113,154,113,106,100,1,83,0,124,3,116,12,107,8, + 114,220,116,0,124,2,100,6,131,2,114,226,122,14,124,2, + 160,13,124,0,161,1,125,7,87,0,110,20,4,0,116,2, + 107,10,114,206,1,0,1,0,1,0,89,0,113,226,88,0, + 124,7,114,226,103,0,124,4,95,14,110,6,124,3,124,4, + 95,14,124,4,106,14,103,0,107,2,144,1,114,12,124,1, + 144,1,114,12,116,15,124,1,131,1,100,7,25,0,125,8, + 124,4,106,14,160,16,124,8,161,1,1,0,124,4,83,0, + 41,8,97,61,1,0,0,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,97,32,102,105,108,101,32,108,111,99,97, + 116,105,111,110,46,10,10,32,32,32,32,84,111,32,105,110, + 100,105,99,97,116,101,32,116,104,97,116,32,116,104,101,32, + 109,111,100,117,108,101,32,105,115,32,97,32,112,97,99,107, + 97,103,101,44,32,115,101,116,10,32,32,32,32,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,32,116,111,32,97,32,108,105,115, + 116,32,111,102,32,100,105,114,101,99,116,111,114,121,32,112, + 97,116,104,115,46,32,32,65,110,10,32,32,32,32,101,109, + 112,116,121,32,108,105,115,116,32,105,115,32,115,117,102,102, + 105,99,105,101,110,116,44,32,116,104,111,117,103,104,32,105, + 116,115,32,110,111,116,32,111,116,104,101,114,119,105,115,101, + 32,117,115,101,102,117,108,32,116,111,32,116,104,101,10,32, + 32,32,32,105,109,112,111,114,116,32,115,121,115,116,101,109, + 46,10,10,32,32,32,32,84,104,101,32,108,111,97,100,101, + 114,32,109,117,115,116,32,116,97,107,101,32,97,32,115,112, + 101,99,32,97,115,32,105,116,115,32,111,110,108,121,32,95, + 95,105,110,105,116,95,95,40,41,32,97,114,103,46,10,10, + 32,32,32,32,78,122,9,60,117,110,107,110,111,119,110,62, + 218,12,103,101,116,95,102,105,108,101,110,97,109,101,169,1, + 218,6,111,114,105,103,105,110,84,218,10,105,115,95,112,97, + 99,107,97,103,101,114,73,0,0,0,41,17,114,129,0,0, + 0,114,180,0,0,0,114,118,0,0,0,114,2,0,0,0, + 114,79,0,0,0,114,135,0,0,0,218,10,77,111,100,117, + 108,101,83,112,101,99,90,13,95,115,101,116,95,102,105,108, + 101,97,116,116,114,218,27,95,103,101,116,95,115,117,112,112, + 111,114,116,101,100,95,102,105,108,101,95,108,111,97,100,101, + 114,115,114,111,0,0,0,114,112,0,0,0,114,141,0,0, + 0,218,9,95,80,79,80,85,76,65,84,69,114,183,0,0, + 0,114,179,0,0,0,114,47,0,0,0,218,6,97,112,112, + 101,110,100,41,9,114,117,0,0,0,90,8,108,111,99,97, + 116,105,111,110,114,141,0,0,0,114,179,0,0,0,218,4, + 115,112,101,99,218,12,108,111,97,100,101,114,95,99,108,97, + 115,115,218,8,115,117,102,102,105,120,101,115,114,183,0,0, + 0,90,7,100,105,114,110,97,109,101,114,3,0,0,0,114, + 3,0,0,0,114,6,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,117,2,0,0,115,62,0,0,0,0,12,8,4,4, + 1,10,2,2,1,14,1,14,1,8,2,10,8,16,1,6, + 3,8,1,14,1,14,1,10,1,6,1,6,2,4,3,8, + 2,10,1,2,1,14,1,14,1,6,2,4,1,8,2,6, + 1,12,1,6,1,12,1,12,2,114,191,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,80,0,0,0,101,0,90,1, + 100,0,90,2,100,1,90,3,100,2,90,4,100,3,90,5, + 100,4,90,6,101,7,100,5,100,6,132,0,131,1,90,8, + 101,7,100,7,100,8,132,0,131,1,90,9,101,7,100,14, + 100,10,100,11,132,1,131,1,90,10,101,7,100,15,100,12, + 100,13,132,1,131,1,90,11,100,9,83,0,41,16,218,21, + 87,105,110,100,111,119,115,82,101,103,105,115,116,114,121,70, + 105,110,100,101,114,122,62,77,101,116,97,32,112,97,116,104, + 32,102,105,110,100,101,114,32,102,111,114,32,109,111,100,117, + 108,101,115,32,100,101,99,108,97,114,101,100,32,105,110,32, + 116,104,101,32,87,105,110,100,111,119,115,32,114,101,103,105, + 115,116,114,121,46,122,59,83,111,102,116,119,97,114,101,92, + 80,121,116,104,111,110,92,80,121,116,104,111,110,67,111,114, + 101,92,123,115,121,115,95,118,101,114,115,105,111,110,125,92, + 77,111,100,117,108,101,115,92,123,102,117,108,108,110,97,109, + 101,125,122,65,83,111,102,116,119,97,114,101,92,80,121,116, + 104,111,110,92,80,121,116,104,111,110,67,111,114,101,92,123, + 115,121,115,95,118,101,114,115,105,111,110,125,92,77,111,100, + 117,108,101,115,92,123,102,117,108,108,110,97,109,101,125,92, + 68,101,98,117,103,70,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,8,0,0,0,67,0,0,0,115, + 56,0,0,0,122,16,116,0,160,1,116,0,106,2,124,1, + 161,2,87,0,83,0,4,0,116,3,107,10,114,50,1,0, + 1,0,1,0,116,0,160,1,116,0,106,4,124,1,161,2, + 6,0,89,0,83,0,88,0,100,0,83,0,114,110,0,0, + 0,41,5,218,7,95,119,105,110,114,101,103,90,7,79,112, + 101,110,75,101,121,90,17,72,75,69,89,95,67,85,82,82, + 69,78,84,95,85,83,69,82,114,50,0,0,0,90,18,72, + 75,69,89,95,76,79,67,65,76,95,77,65,67,72,73,78, + 69,41,2,218,3,99,108,115,114,5,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,14,95,111, + 112,101,110,95,114,101,103,105,115,116,114,121,197,2,0,0, + 115,8,0,0,0,0,2,2,1,16,1,14,1,122,36,87, + 105,110,100,111,119,115,82,101,103,105,115,116,114,121,70,105, + 110,100,101,114,46,95,111,112,101,110,95,114,101,103,105,115, + 116,114,121,99,2,0,0,0,0,0,0,0,0,0,0,0, + 6,0,0,0,9,0,0,0,67,0,0,0,115,114,0,0, + 0,124,0,106,0,114,14,124,0,106,1,125,2,110,6,124, + 0,106,2,125,2,124,2,106,3,124,1,100,1,116,4,106, + 5,100,0,100,2,133,2,25,0,22,0,100,3,141,2,125, + 3,122,38,124,0,160,6,124,3,161,1,143,18,125,4,116, + 7,160,8,124,4,100,4,161,2,125,5,87,0,53,0,81, + 0,82,0,88,0,87,0,110,22,4,0,116,9,107,10,114, + 108,1,0,1,0,1,0,89,0,100,0,83,0,88,0,124, 5,83,0,41,5,78,122,5,37,100,46,37,100,114,28,0, - 0,0,41,2,114,139,0,0,0,90,11,115,121,115,95,118, + 0,0,41,2,114,140,0,0,0,90,11,115,121,115,95,118, 101,114,115,105,111,110,114,40,0,0,0,41,10,218,11,68, 69,66,85,71,95,66,85,73,76,68,218,18,82,69,71,73, 83,84,82,89,95,75,69,89,95,68,69,66,85,71,218,12, 82,69,71,73,83,84,82,89,95,75,69,89,114,62,0,0, 0,114,8,0,0,0,218,12,118,101,114,115,105,111,110,95, - 105,110,102,111,114,194,0,0,0,114,192,0,0,0,90,10, + 105,110,102,111,114,195,0,0,0,114,193,0,0,0,90,10, 81,117,101,114,121,86,97,108,117,101,114,50,0,0,0,41, - 6,114,193,0,0,0,114,139,0,0,0,90,12,114,101,103, + 6,114,194,0,0,0,114,140,0,0,0,90,12,114,101,103, 105,115,116,114,121,95,107,101,121,114,5,0,0,0,90,4, 104,107,101,121,218,8,102,105,108,101,112,97,116,104,114,3, 0,0,0,114,3,0,0,0,114,6,0,0,0,218,16,95, - 115,101,97,114,99,104,95,114,101,103,105,115,116,114,121,199, + 115,101,97,114,99,104,95,114,101,103,105,115,116,114,121,204, 2,0,0,115,24,0,0,0,0,2,6,1,8,2,6,1, - 6,1,16,255,6,2,2,1,12,1,26,1,14,1,12,1, + 6,1,16,255,6,2,2,1,12,1,26,1,14,1,8,1, 122,38,87,105,110,100,111,119,115,82,101,103,105,115,116,114, 121,70,105,110,100,101,114,46,95,115,101,97,114,99,104,95, 114,101,103,105,115,116,114,121,78,99,4,0,0,0,0,0, @@ -1026,15 +1024,15 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 4,160,4,116,5,124,6,131,1,161,1,114,64,116,6,106, 7,124,1,124,5,124,1,124,4,131,2,124,4,100,1,141, 3,125,7,124,7,2,0,1,0,83,0,113,64,100,0,83, - 0,41,2,78,114,180,0,0,0,41,8,114,200,0,0,0, - 114,49,0,0,0,114,50,0,0,0,114,184,0,0,0,114, - 111,0,0,0,114,112,0,0,0,114,134,0,0,0,218,16, + 0,41,2,78,114,181,0,0,0,41,8,114,201,0,0,0, + 114,49,0,0,0,114,50,0,0,0,114,185,0,0,0,114, + 111,0,0,0,114,112,0,0,0,114,135,0,0,0,218,16, 115,112,101,99,95,102,114,111,109,95,108,111,97,100,101,114, - 41,8,114,193,0,0,0,114,139,0,0,0,114,44,0,0, - 0,218,6,116,97,114,103,101,116,114,199,0,0,0,114,140, - 0,0,0,114,189,0,0,0,114,187,0,0,0,114,3,0, + 41,8,114,194,0,0,0,114,140,0,0,0,114,44,0,0, + 0,218,6,116,97,114,103,101,116,114,200,0,0,0,114,141, + 0,0,0,114,190,0,0,0,114,188,0,0,0,114,3,0, 0,0,114,3,0,0,0,114,6,0,0,0,218,9,102,105, - 110,100,95,115,112,101,99,214,2,0,0,115,28,0,0,0, + 110,100,95,115,112,101,99,219,2,0,0,115,28,0,0,0, 0,2,10,1,8,1,4,1,2,1,12,1,14,1,8,1, 14,1,14,1,6,1,8,1,2,254,6,3,122,31,87,105, 110,100,111,119,115,82,101,103,105,115,116,114,121,70,105,110, @@ -1050,1788 +1048,1687 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 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,78,169,2, - 114,203,0,0,0,114,140,0,0,0,169,4,114,193,0,0, - 0,114,139,0,0,0,114,44,0,0,0,114,187,0,0,0, + 114,204,0,0,0,114,141,0,0,0,169,4,114,194,0,0, + 0,114,140,0,0,0,114,44,0,0,0,114,188,0,0,0, 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 11,102,105,110,100,95,109,111,100,117,108,101,230,2,0,0, + 11,102,105,110,100,95,109,111,100,117,108,101,235,2,0,0, 115,8,0,0,0,0,7,12,1,8,1,6,2,122,33,87, 105,110,100,111,119,115,82,101,103,105,115,116,114,121,70,105, 110,100,101,114,46,102,105,110,100,95,109,111,100,117,108,101, - 41,12,114,125,0,0,0,114,124,0,0,0,114,126,0,0, - 0,114,127,0,0,0,114,197,0,0,0,114,196,0,0,0, - 114,195,0,0,0,218,11,99,108,97,115,115,109,101,116,104, - 111,100,114,194,0,0,0,114,200,0,0,0,114,203,0,0, - 0,114,206,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,191,0,0,0,180, - 2,0,0,115,28,0,0,0,8,2,4,3,2,255,2,4, - 2,255,2,3,4,2,2,1,10,6,2,1,10,14,2,1, - 16,15,2,1,114,191,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,13,95,76,111,97,100, - 101,114,66,97,115,105,99,115,122,83,66,97,115,101,32,99, - 108,97,115,115,32,111,102,32,99,111,109,109,111,110,32,99, - 111,100,101,32,110,101,101,100,101,100,32,98,121,32,98,111, - 116,104,32,83,111,117,114,99,101,76,111,97,100,101,114,32, - 97,110,100,10,32,32,32,32,83,111,117,114,99,101,108,101, - 115,115,70,105,108,101,76,111,97,100,101,114,46,99,2,0, - 0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0, - 0,0,67,0,0,0,115,64,0,0,0,116,0,124,0,160, - 1,124,1,161,1,131,1,100,1,25,0,125,2,124,2,160, - 2,100,2,100,1,161,2,100,3,25,0,125,3,124,1,160, - 3,100,2,161,1,100,4,25,0,125,4,124,3,100,5,107, - 2,111,62,124,4,100,5,107,3,83,0,41,6,122,141,67, - 111,110,99,114,101,116,101,32,105,109,112,108,101,109,101,110, - 116,97,116,105,111,110,32,111,102,32,73,110,115,112,101,99, - 116,76,111,97,100,101,114,46,105,115,95,112,97,99,107,97, - 103,101,32,98,121,32,99,104,101,99,107,105,110,103,32,105, - 102,10,32,32,32,32,32,32,32,32,116,104,101,32,112,97, - 116,104,32,114,101,116,117,114,110,101,100,32,98,121,32,103, - 101,116,95,102,105,108,101,110,97,109,101,32,104,97,115,32, - 97,32,102,105,108,101,110,97,109,101,32,111,102,32,39,95, - 95,105,110,105,116,95,95,46,112,121,39,46,114,39,0,0, - 0,114,71,0,0,0,114,73,0,0,0,114,28,0,0,0, - 218,8,95,95,105,110,105,116,95,95,41,4,114,47,0,0, - 0,114,179,0,0,0,114,43,0,0,0,114,41,0,0,0, - 41,5,114,119,0,0,0,114,139,0,0,0,114,97,0,0, - 0,90,13,102,105,108,101,110,97,109,101,95,98,97,115,101, - 90,9,116,97,105,108,95,110,97,109,101,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,182,0,0,0,249, - 2,0,0,115,8,0,0,0,0,3,18,1,16,1,14,1, - 122,24,95,76,111,97,100,101,114,66,97,115,105,99,115,46, - 105,115,95,112,97,99,107,97,103,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,169,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,3,0,0,0, - 169,2,114,119,0,0,0,114,187,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,13,99,114,101, - 97,116,101,95,109,111,100,117,108,101,1,3,0,0,115,2, - 0,0,0,0,1,122,27,95,76,111,97,100,101,114,66,97, - 115,105,99,115,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,3, - 0,0,0,5,0,0,0,67,0,0,0,115,56,0,0,0, - 124,0,160,0,124,1,106,1,161,1,125,2,124,2,100,1, - 107,8,114,36,116,2,100,2,160,3,124,1,106,1,161,1, - 131,1,130,1,116,4,160,5,116,6,124,2,124,1,106,7, - 161,3,1,0,100,1,83,0,41,3,122,19,69,120,101,99, - 117,116,101,32,116,104,101,32,109,111,100,117,108,101,46,78, - 122,52,99,97,110,110,111,116,32,108,111,97,100,32,109,111, - 100,117,108,101,32,123,33,114,125,32,119,104,101,110,32,103, - 101,116,95,99,111,100,101,40,41,32,114,101,116,117,114,110, - 115,32,78,111,110,101,41,8,218,8,103,101,116,95,99,111, - 100,101,114,125,0,0,0,114,118,0,0,0,114,62,0,0, - 0,114,134,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,218,4,101,120,101,99,114,131,0,0,0,41,3,114,119, - 0,0,0,218,6,109,111,100,117,108,101,114,164,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 11,101,120,101,99,95,109,111,100,117,108,101,4,3,0,0, - 115,12,0,0,0,0,2,12,1,8,1,6,1,4,255,6, - 2,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, - 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,4,0,0, - 0,67,0,0,0,115,12,0,0,0,116,0,160,1,124,0, - 124,1,161,2,83,0,41,1,122,26,84,104,105,115,32,109, - 111,100,117,108,101,32,105,115,32,100,101,112,114,101,99,97, - 116,101,100,46,41,2,114,134,0,0,0,218,17,95,108,111, - 97,100,95,109,111,100,117,108,101,95,115,104,105,109,169,2, - 114,119,0,0,0,114,139,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,11,108,111,97,100,95, - 109,111,100,117,108,101,12,3,0,0,115,2,0,0,0,0, - 2,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, - 46,108,111,97,100,95,109,111,100,117,108,101,78,41,8,114, - 125,0,0,0,114,124,0,0,0,114,126,0,0,0,114,127, - 0,0,0,114,182,0,0,0,114,212,0,0,0,114,217,0, - 0,0,114,220,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,208,0,0,0, - 244,2,0,0,115,10,0,0,0,8,2,4,3,8,8,8, - 3,8,8,114,208,0,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, - 0,115,74,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,100,8,132,0,90,6,100,9, - 100,10,132,0,90,7,100,11,100,12,156,1,100,13,100,14, - 132,2,90,8,100,15,100,16,132,0,90,9,100,17,83,0, - 41,18,218,12,83,111,117,114,99,101,76,111,97,100,101,114, - 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,8,0,0,0,116,0, - 130,1,100,1,83,0,41,2,122,165,79,112,116,105,111,110, - 97,108,32,109,101,116,104,111,100,32,116,104,97,116,32,114, - 101,116,117,114,110,115,32,116,104,101,32,109,111,100,105,102, - 105,99,97,116,105,111,110,32,116,105,109,101,32,40,97,110, - 32,105,110,116,41,32,102,111,114,32,116,104,101,10,32,32, - 32,32,32,32,32,32,115,112,101,99,105,102,105,101,100,32, - 112,97,116,104,32,40,97,32,115,116,114,41,46,10,10,32, - 32,32,32,32,32,32,32,82,97,105,115,101,115,32,79,83, - 69,114,114,111,114,32,119,104,101,110,32,116,104,101,32,112, - 97,116,104,32,99,97,110,110,111,116,32,98,101,32,104,97, - 110,100,108,101,100,46,10,32,32,32,32,32,32,32,32,78, - 41,1,114,50,0,0,0,169,2,114,119,0,0,0,114,44, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,10,112,97,116,104,95,109,116,105,109,101,19,3, - 0,0,115,2,0,0,0,0,6,122,23,83,111,117,114,99, - 101,76,111,97,100,101,114,46,112,97,116,104,95,109,116,105, - 109,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,14,0,0,0, - 100,1,124,0,160,0,124,1,161,1,105,1,83,0,41,2, - 97,158,1,0,0,79,112,116,105,111,110,97,108,32,109,101, - 116,104,111,100,32,114,101,116,117,114,110,105,110,103,32,97, - 32,109,101,116,97,100,97,116,97,32,100,105,99,116,32,102, - 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 10,32,32,32,32,32,32,32,32,112,97,116,104,32,40,97, - 32,115,116,114,41,46,10,10,32,32,32,32,32,32,32,32, - 80,111,115,115,105,98,108,101,32,107,101,121,115,58,10,32, - 32,32,32,32,32,32,32,45,32,39,109,116,105,109,101,39, - 32,40,109,97,110,100,97,116,111,114,121,41,32,105,115,32, - 116,104,101,32,110,117,109,101,114,105,99,32,116,105,109,101, - 115,116,97,109,112,32,111,102,32,108,97,115,116,32,115,111, - 117,114,99,101,10,32,32,32,32,32,32,32,32,32,32,99, - 111,100,101,32,109,111,100,105,102,105,99,97,116,105,111,110, - 59,10,32,32,32,32,32,32,32,32,45,32,39,115,105,122, - 101,39,32,40,111,112,116,105,111,110,97,108,41,32,105,115, - 32,116,104,101,32,115,105,122,101,32,105,110,32,98,121,116, - 101,115,32,111,102,32,116,104,101,32,115,111,117,114,99,101, - 32,99,111,100,101,46,10,10,32,32,32,32,32,32,32,32, - 73,109,112,108,101,109,101,110,116,105,110,103,32,116,104,105, - 115,32,109,101,116,104,111,100,32,97,108,108,111,119,115,32, - 116,104,101,32,108,111,97,100,101,114,32,116,111,32,114,101, - 97,100,32,98,121,116,101,99,111,100,101,32,102,105,108,101, - 115,46,10,32,32,32,32,32,32,32,32,82,97,105,115,101, - 115,32,79,83,69,114,114,111,114,32,119,104,101,110,32,116, - 104,101,32,112,97,116,104,32,99,97,110,110,111,116,32,98, - 101,32,104,97,110,100,108,101,100,46,10,32,32,32,32,32, - 32,32,32,114,169,0,0,0,41,1,114,223,0,0,0,114, - 222,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,10,112,97,116,104,95,115,116,97,116,115,27, - 3,0,0,115,2,0,0,0,0,12,122,23,83,111,117,114, - 99,101,76,111,97,100,101,114,46,112,97,116,104,95,115,116, - 97,116,115,99,4,0,0,0,0,0,0,0,0,0,0,0, - 4,0,0,0,4,0,0,0,67,0,0,0,115,12,0,0, - 0,124,0,160,0,124,2,124,3,161,2,83,0,41,1,122, - 228,79,112,116,105,111,110,97,108,32,109,101,116,104,111,100, - 32,119,104,105,99,104,32,119,114,105,116,101,115,32,100,97, - 116,97,32,40,98,121,116,101,115,41,32,116,111,32,97,32, - 102,105,108,101,32,112,97,116,104,32,40,97,32,115,116,114, - 41,46,10,10,32,32,32,32,32,32,32,32,73,109,112,108, - 101,109,101,110,116,105,110,103,32,116,104,105,115,32,109,101, - 116,104,111,100,32,97,108,108,111,119,115,32,102,111,114,32, - 116,104,101,32,119,114,105,116,105,110,103,32,111,102,32,98, - 121,116,101,99,111,100,101,32,102,105,108,101,115,46,10,10, - 32,32,32,32,32,32,32,32,84,104,101,32,115,111,117,114, - 99,101,32,112,97,116,104,32,105,115,32,110,101,101,100,101, - 100,32,105,110,32,111,114,100,101,114,32,116,111,32,99,111, - 114,114,101,99,116,108,121,32,116,114,97,110,115,102,101,114, - 32,112,101,114,109,105,115,115,105,111,110,115,10,32,32,32, - 32,32,32,32,32,41,1,218,8,115,101,116,95,100,97,116, - 97,41,4,114,119,0,0,0,114,108,0,0,0,90,10,99, - 97,99,104,101,95,112,97,116,104,114,26,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,15,95, - 99,97,99,104,101,95,98,121,116,101,99,111,100,101,41,3, - 0,0,115,2,0,0,0,0,8,122,28,83,111,117,114,99, - 101,76,111,97,100,101,114,46,95,99,97,99,104,101,95,98, - 121,116,101,99,111,100,101,99,3,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,1,0,0,0,67,0,0,0, - 115,4,0,0,0,100,1,83,0,41,2,122,150,79,112,116, - 105,111,110,97,108,32,109,101,116,104,111,100,32,119,104,105, - 99,104,32,119,114,105,116,101,115,32,100,97,116,97,32,40, - 98,121,116,101,115,41,32,116,111,32,97,32,102,105,108,101, - 32,112,97,116,104,32,40,97,32,115,116,114,41,46,10,10, - 32,32,32,32,32,32,32,32,73,109,112,108,101,109,101,110, - 116,105,110,103,32,116,104,105,115,32,109,101,116,104,111,100, - 32,97,108,108,111,119,115,32,102,111,114,32,116,104,101,32, - 119,114,105,116,105,110,103,32,111,102,32,98,121,116,101,99, - 111,100,101,32,102,105,108,101,115,46,10,32,32,32,32,32, - 32,32,32,78,114,3,0,0,0,41,3,114,119,0,0,0, - 114,44,0,0,0,114,26,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,225,0,0,0,51,3, - 0,0,115,2,0,0,0,0,1,122,21,83,111,117,114,99, - 101,76,111,97,100,101,114,46,115,101,116,95,100,97,116,97, - 99,2,0,0,0,0,0,0,0,0,0,0,0,5,0,0, - 0,10,0,0,0,67,0,0,0,115,82,0,0,0,124,0, - 160,0,124,1,161,1,125,2,122,14,124,0,160,1,124,2, - 161,1,125,3,87,0,110,48,4,0,116,2,107,10,114,72, - 1,0,125,4,1,0,122,18,116,3,100,1,124,1,100,2, - 141,2,124,4,130,2,87,0,53,0,100,3,125,4,126,4, - 88,0,89,0,110,2,88,0,116,4,124,3,131,1,83,0, - 41,4,122,52,67,111,110,99,114,101,116,101,32,105,109,112, - 108,101,109,101,110,116,97,116,105,111,110,32,111,102,32,73, - 110,115,112,101,99,116,76,111,97,100,101,114,46,103,101,116, - 95,115,111,117,114,99,101,46,122,39,115,111,117,114,99,101, - 32,110,111,116,32,97,118,97,105,108,97,98,108,101,32,116, - 104,114,111,117,103,104,32,103,101,116,95,100,97,116,97,40, - 41,114,116,0,0,0,78,41,5,114,179,0,0,0,218,8, - 103,101,116,95,100,97,116,97,114,50,0,0,0,114,118,0, - 0,0,114,176,0,0,0,41,5,114,119,0,0,0,114,139, - 0,0,0,114,44,0,0,0,114,174,0,0,0,218,3,101, - 120,99,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,10,103,101,116,95,115,111,117,114,99,101,58,3,0, - 0,115,20,0,0,0,0,2,10,1,2,1,14,1,16,1, - 4,1,2,255,4,1,2,255,20,2,122,23,83,111,117,114, - 99,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117, - 114,99,101,114,105,0,0,0,41,1,218,9,95,111,112,116, - 105,109,105,122,101,99,3,0,0,0,0,0,0,0,1,0, - 0,0,4,0,0,0,8,0,0,0,67,0,0,0,115,22, - 0,0,0,116,0,106,1,116,2,124,1,124,2,100,1,100, - 2,124,3,100,3,141,6,83,0,41,4,122,130,82,101,116, - 117,114,110,32,116,104,101,32,99,111,100,101,32,111,98,106, - 101,99,116,32,99,111,109,112,105,108,101,100,32,102,114,111, - 109,32,115,111,117,114,99,101,46,10,10,32,32,32,32,32, - 32,32,32,84,104,101,32,39,100,97,116,97,39,32,97,114, - 103,117,109,101,110,116,32,99,97,110,32,98,101,32,97,110, - 121,32,111,98,106,101,99,116,32,116,121,112,101,32,116,104, - 97,116,32,99,111,109,112,105,108,101,40,41,32,115,117,112, - 112,111,114,116,115,46,10,32,32,32,32,32,32,32,32,114, - 215,0,0,0,84,41,2,218,12,100,111,110,116,95,105,110, - 104,101,114,105,116,114,84,0,0,0,41,3,114,134,0,0, - 0,114,214,0,0,0,218,7,99,111,109,112,105,108,101,41, - 4,114,119,0,0,0,114,26,0,0,0,114,44,0,0,0, - 114,230,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,14,115,111,117,114,99,101,95,116,111,95, - 99,111,100,101,68,3,0,0,115,8,0,0,0,0,5,12, - 1,2,0,2,255,122,27,83,111,117,114,99,101,76,111,97, - 100,101,114,46,115,111,117,114,99,101,95,116,111,95,99,111, - 100,101,99,2,0,0,0,0,0,0,0,0,0,0,0,15, - 0,0,0,9,0,0,0,67,0,0,0,115,34,2,0,0, - 124,0,160,0,124,1,161,1,125,2,100,1,125,3,100,1, - 125,4,100,1,125,5,100,2,125,6,100,3,125,7,122,12, - 116,1,124,2,131,1,125,8,87,0,110,26,4,0,116,2, - 107,10,114,68,1,0,1,0,1,0,100,1,125,8,89,0, - 144,1,110,48,88,0,122,14,124,0,160,3,124,2,161,1, - 125,9,87,0,110,22,4,0,116,4,107,10,114,106,1,0, - 1,0,1,0,89,0,144,1,110,10,88,0,116,5,124,9, - 100,4,25,0,131,1,125,3,122,14,124,0,160,6,124,8, - 161,1,125,10,87,0,110,20,4,0,116,4,107,10,114,154, - 1,0,1,0,1,0,89,0,110,218,88,0,124,1,124,8, - 100,5,156,2,125,11,122,148,116,7,124,10,124,1,124,11, - 131,3,125,12,116,8,124,10,131,1,100,6,100,1,133,2, - 25,0,125,13,124,12,100,7,64,0,100,8,107,3,125,6, - 124,6,144,1,114,36,124,12,100,9,64,0,100,8,107,3, - 125,7,116,9,106,10,100,10,107,3,144,1,114,34,124,7, - 115,254,116,9,106,10,100,11,107,2,144,1,114,34,124,0, - 160,6,124,2,161,1,125,4,116,9,160,11,116,12,124,4, - 161,2,125,5,116,13,124,10,124,5,124,1,124,11,131,4, - 1,0,110,20,116,14,124,10,124,3,124,9,100,12,25,0, - 124,1,124,11,131,5,1,0,87,0,110,26,4,0,116,15, - 116,16,102,2,107,10,144,1,114,84,1,0,1,0,1,0, - 89,0,110,32,88,0,116,17,160,18,100,13,124,8,124,2, - 161,3,1,0,116,19,124,13,124,1,124,8,124,2,100,14, - 141,4,83,0,124,4,100,1,107,8,144,1,114,136,124,0, - 160,6,124,2,161,1,125,4,124,0,160,20,124,4,124,2, - 161,2,125,14,116,17,160,18,100,15,124,2,161,2,1,0, - 116,21,106,22,144,2,115,30,124,8,100,1,107,9,144,2, - 114,30,124,3,100,1,107,9,144,2,114,30,124,6,144,1, - 114,228,124,5,100,1,107,8,144,1,114,214,116,9,160,11, - 124,4,161,1,125,5,116,23,124,14,124,5,124,7,131,3, - 125,10,110,16,116,24,124,14,124,3,116,25,124,4,131,1, - 131,3,125,10,122,18,124,0,160,26,124,2,124,8,124,10, - 161,3,1,0,87,0,110,22,4,0,116,2,107,10,144,2, - 114,28,1,0,1,0,1,0,89,0,110,2,88,0,124,14, - 83,0,41,16,122,190,67,111,110,99,114,101,116,101,32,105, - 109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102, - 32,73,110,115,112,101,99,116,76,111,97,100,101,114,46,103, - 101,116,95,99,111,100,101,46,10,10,32,32,32,32,32,32, - 32,32,82,101,97,100,105,110,103,32,111,102,32,98,121,116, - 101,99,111,100,101,32,114,101,113,117,105,114,101,115,32,112, - 97,116,104,95,115,116,97,116,115,32,116,111,32,98,101,32, - 105,109,112,108,101,109,101,110,116,101,100,46,32,84,111,32, - 119,114,105,116,101,10,32,32,32,32,32,32,32,32,98,121, - 116,101,99,111,100,101,44,32,115,101,116,95,100,97,116,97, - 32,109,117,115,116,32,97,108,115,111,32,98,101,32,105,109, - 112,108,101,109,101,110,116,101,100,46,10,10,32,32,32,32, - 32,32,32,32,78,70,84,114,169,0,0,0,114,159,0,0, - 0,114,145,0,0,0,114,39,0,0,0,114,73,0,0,0, - 114,28,0,0,0,90,5,110,101,118,101,114,90,6,97,108, - 119,97,121,115,218,4,115,105,122,101,122,13,123,125,32,109, - 97,116,99,104,101,115,32,123,125,41,3,114,117,0,0,0, - 114,107,0,0,0,114,108,0,0,0,122,19,99,111,100,101, - 32,111,98,106,101,99,116,32,102,114,111,109,32,123,125,41, - 27,114,179,0,0,0,114,98,0,0,0,114,82,0,0,0, - 114,224,0,0,0,114,50,0,0,0,114,17,0,0,0,114, - 227,0,0,0,114,152,0,0,0,218,10,109,101,109,111,114, - 121,118,105,101,119,114,163,0,0,0,90,21,99,104,101,99, - 107,95,104,97,115,104,95,98,97,115,101,100,95,112,121,99, - 115,114,157,0,0,0,218,17,95,82,65,87,95,77,65,71, - 73,67,95,78,85,77,66,69,82,114,158,0,0,0,114,156, - 0,0,0,114,118,0,0,0,114,150,0,0,0,114,134,0, - 0,0,114,149,0,0,0,114,165,0,0,0,114,233,0,0, - 0,114,8,0,0,0,218,19,100,111,110,116,95,119,114,105, - 116,101,95,98,121,116,101,99,111,100,101,114,171,0,0,0, - 114,170,0,0,0,114,22,0,0,0,114,226,0,0,0,41, - 15,114,119,0,0,0,114,139,0,0,0,114,108,0,0,0, - 114,154,0,0,0,114,174,0,0,0,114,157,0,0,0,90, - 10,104,97,115,104,95,98,97,115,101,100,90,12,99,104,101, - 99,107,95,115,111,117,114,99,101,114,107,0,0,0,218,2, - 115,116,114,26,0,0,0,114,151,0,0,0,114,83,0,0, - 0,90,10,98,121,116,101,115,95,100,97,116,97,90,11,99, - 111,100,101,95,111,98,106,101,99,116,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,213,0,0,0,76,3, - 0,0,115,152,0,0,0,0,7,10,1,4,1,4,1,4, - 1,4,1,4,1,2,1,12,1,14,1,12,2,2,1,14, - 1,14,1,8,2,12,1,2,1,14,1,14,1,6,3,2, - 1,2,254,6,4,2,1,12,1,16,1,12,1,6,1,12, - 1,12,1,2,255,2,2,8,254,4,3,10,1,4,1,2, - 1,2,254,4,4,8,1,2,255,6,3,2,1,2,1,2, - 1,6,1,2,1,2,251,8,7,20,1,6,2,8,1,2, - 255,4,2,6,1,2,1,2,254,6,3,10,1,10,1,12, - 1,12,1,18,1,6,255,4,2,6,1,10,1,10,1,14, - 2,6,1,6,255,4,2,2,1,18,1,16,1,6,1,122, - 21,83,111,117,114,99,101,76,111,97,100,101,114,46,103,101, - 116,95,99,111,100,101,78,41,10,114,125,0,0,0,114,124, - 0,0,0,114,126,0,0,0,114,223,0,0,0,114,224,0, - 0,0,114,226,0,0,0,114,225,0,0,0,114,229,0,0, - 0,114,233,0,0,0,114,213,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 221,0,0,0,17,3,0,0,115,14,0,0,0,8,2,8, - 8,8,14,8,10,8,7,8,10,14,8,114,221,0,0,0, + 41,2,78,78,41,1,78,41,12,114,126,0,0,0,114,125, + 0,0,0,114,127,0,0,0,114,128,0,0,0,114,198,0, + 0,0,114,197,0,0,0,114,196,0,0,0,218,11,99,108, + 97,115,115,109,101,116,104,111,100,114,195,0,0,0,114,201, + 0,0,0,114,204,0,0,0,114,207,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,192,0,0,0,185,2,0,0,115,28,0,0,0,8, + 2,4,3,2,255,2,4,2,255,2,3,4,2,2,1,10, + 6,2,1,10,14,2,1,12,15,2,1,114,192,0,0,0, 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,0,0,0,0,115,124,0,0,0,101,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,101,7,135,0,102,1,100,8,100,9,132,8,131,1, - 90,8,101,7,100,10,100,11,132,0,131,1,90,9,100,12, - 100,13,132,0,90,10,101,7,100,14,100,15,132,0,131,1, - 90,11,100,16,100,17,132,0,90,12,100,18,100,19,132,0, - 90,13,100,20,100,21,132,0,90,14,100,22,100,23,132,0, - 90,15,135,0,4,0,90,16,83,0,41,24,218,10,70,105, - 108,101,76,111,97,100,101,114,122,103,66,97,115,101,32,102, - 105,108,101,32,108,111,97,100,101,114,32,99,108,97,115,115, - 32,119,104,105,99,104,32,105,109,112,108,101,109,101,110,116, - 115,32,116,104,101,32,108,111,97,100,101,114,32,112,114,111, - 116,111,99,111,108,32,109,101,116,104,111,100,115,32,116,104, - 97,116,10,32,32,32,32,114,101,113,117,105,114,101,32,102, - 105,108,101,32,115,121,115,116,101,109,32,117,115,97,103,101, - 46,99,3,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,124, - 1,124,0,95,0,124,2,124,0,95,1,100,1,83,0,41, - 2,122,75,67,97,99,104,101,32,116,104,101,32,109,111,100, - 117,108,101,32,110,97,109,101,32,97,110,100,32,116,104,101, - 32,112,97,116,104,32,116,111,32,116,104,101,32,102,105,108, - 101,32,102,111,117,110,100,32,98,121,32,116,104,101,10,32, - 32,32,32,32,32,32,32,102,105,110,100,101,114,46,78,114, - 159,0,0,0,41,3,114,119,0,0,0,114,139,0,0,0, - 114,44,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,209,0,0,0,166,3,0,0,115,4,0, - 0,0,0,3,6,1,122,19,70,105,108,101,76,111,97,100, - 101,114,46,95,95,105,110,105,116,95,95,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,24,0,0,0,124,0,106,0,124,1,106, - 0,107,2,111,22,124,0,106,1,124,1,106,1,107,2,83, - 0,114,110,0,0,0,169,2,218,9,95,95,99,108,97,115, - 115,95,95,114,131,0,0,0,169,2,114,119,0,0,0,90, - 5,111,116,104,101,114,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,6,95,95,101,113,95,95,172,3,0, - 0,115,6,0,0,0,0,1,12,1,10,255,122,17,70,105, - 108,101,76,111,97,100,101,114,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,20,0,0,0,116,0,124, - 0,106,1,131,1,116,0,124,0,106,2,131,1,65,0,83, - 0,114,110,0,0,0,169,3,218,4,104,97,115,104,114,117, - 0,0,0,114,44,0,0,0,169,1,114,119,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,8, - 95,95,104,97,115,104,95,95,176,3,0,0,115,2,0,0, - 0,0,1,122,19,70,105,108,101,76,111,97,100,101,114,46, - 95,95,104,97,115,104,95,95,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,3,0,0,0,3,0,0, - 0,115,16,0,0,0,116,0,116,1,124,0,131,2,160,2, - 124,1,161,1,83,0,41,1,122,100,76,111,97,100,32,97, - 32,109,111,100,117,108,101,32,102,114,111,109,32,97,32,102, - 105,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,3, - 218,5,115,117,112,101,114,114,239,0,0,0,114,220,0,0, - 0,114,219,0,0,0,169,1,114,241,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,220,0,0,0,179,3,0,0, - 115,2,0,0,0,0,10,122,22,70,105,108,101,76,111,97, - 100,101,114,46,108,111,97,100,95,109,111,100,117,108,101,99, + 90,6,100,8,100,9,132,0,90,7,100,10,83,0,41,11, + 218,13,95,76,111,97,100,101,114,66,97,115,105,99,115,122, + 83,66,97,115,101,32,99,108,97,115,115,32,111,102,32,99, + 111,109,109,111,110,32,99,111,100,101,32,110,101,101,100,101, + 100,32,98,121,32,98,111,116,104,32,83,111,117,114,99,101, + 76,111,97,100,101,114,32,97,110,100,10,32,32,32,32,83, + 111,117,114,99,101,108,101,115,115,70,105,108,101,76,111,97, + 100,101,114,46,99,2,0,0,0,0,0,0,0,0,0,0, + 0,5,0,0,0,4,0,0,0,67,0,0,0,115,64,0, + 0,0,116,0,124,0,160,1,124,1,161,1,131,1,100,1, + 25,0,125,2,124,2,160,2,100,2,100,1,161,2,100,3, + 25,0,125,3,124,1,160,3,100,2,161,1,100,4,25,0, + 125,4,124,3,100,5,107,2,111,62,124,4,100,5,107,3, + 83,0,41,6,122,141,67,111,110,99,114,101,116,101,32,105, + 109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102, + 32,73,110,115,112,101,99,116,76,111,97,100,101,114,46,105, + 115,95,112,97,99,107,97,103,101,32,98,121,32,99,104,101, + 99,107,105,110,103,32,105,102,10,32,32,32,32,32,32,32, + 32,116,104,101,32,112,97,116,104,32,114,101,116,117,114,110, + 101,100,32,98,121,32,103,101,116,95,102,105,108,101,110,97, + 109,101,32,104,97,115,32,97,32,102,105,108,101,110,97,109, + 101,32,111,102,32,39,95,95,105,110,105,116,95,95,46,112, + 121,39,46,114,39,0,0,0,114,71,0,0,0,114,73,0, + 0,0,114,28,0,0,0,218,8,95,95,105,110,105,116,95, + 95,41,4,114,47,0,0,0,114,180,0,0,0,114,43,0, + 0,0,114,41,0,0,0,41,5,114,119,0,0,0,114,140, + 0,0,0,114,97,0,0,0,90,13,102,105,108,101,110,97, + 109,101,95,98,97,115,101,90,9,116,97,105,108,95,110,97, + 109,101,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,183,0,0,0,254,2,0,0,115,8,0,0,0,0, + 3,18,1,16,1,14,1,122,24,95,76,111,97,100,101,114, + 66,97,115,105,99,115,46,105,115,95,112,97,99,107,97,103, + 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,169,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,3,0,0,0,169,2,114,119,0,0,0,114,188, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,13,99,114,101,97,116,101,95,109,111,100,117,108, + 101,6,3,0,0,115,2,0,0,0,0,1,122,27,95,76, + 111,97,100,101,114,66,97,115,105,99,115,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,3,0,0,0,5,0,0,0,67,0, + 0,0,115,56,0,0,0,124,0,160,0,124,1,106,1,161, + 1,125,2,124,2,100,1,107,8,114,36,116,2,100,2,160, + 3,124,1,106,1,161,1,131,1,130,1,116,4,160,5,116, + 6,124,2,124,1,106,7,161,3,1,0,100,1,83,0,41, + 3,122,19,69,120,101,99,117,116,101,32,116,104,101,32,109, + 111,100,117,108,101,46,78,122,52,99,97,110,110,111,116,32, + 108,111,97,100,32,109,111,100,117,108,101,32,123,33,114,125, + 32,119,104,101,110,32,103,101,116,95,99,111,100,101,40,41, + 32,114,101,116,117,114,110,115,32,78,111,110,101,41,8,218, + 8,103,101,116,95,99,111,100,101,114,126,0,0,0,114,118, + 0,0,0,114,62,0,0,0,114,135,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,218,4,101,120,101,99,114,132, + 0,0,0,41,3,114,119,0,0,0,218,6,109,111,100,117, + 108,101,114,165,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,218,11,101,120,101,99,95,109,111,100, + 117,108,101,9,3,0,0,115,12,0,0,0,0,2,12,1, + 8,1,6,1,4,255,6,2,122,25,95,76,111,97,100,101, + 114,66,97,115,105,99,115,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,4,0,0,0,67,0,0,0,115,12,0,0, + 0,116,0,160,1,124,0,124,1,161,2,83,0,41,1,122, + 26,84,104,105,115,32,109,111,100,117,108,101,32,105,115,32, + 100,101,112,114,101,99,97,116,101,100,46,41,2,114,135,0, + 0,0,218,17,95,108,111,97,100,95,109,111,100,117,108,101, + 95,115,104,105,109,169,2,114,119,0,0,0,114,140,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 218,11,108,111,97,100,95,109,111,100,117,108,101,17,3,0, + 0,115,2,0,0,0,0,2,122,25,95,76,111,97,100,101, + 114,66,97,115,105,99,115,46,108,111,97,100,95,109,111,100, + 117,108,101,78,41,8,114,126,0,0,0,114,125,0,0,0, + 114,127,0,0,0,114,128,0,0,0,114,183,0,0,0,114, + 213,0,0,0,114,218,0,0,0,114,221,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,209,0,0,0,249,2,0,0,115,10,0,0,0, + 8,2,4,3,8,8,8,3,8,8,114,209,0,0,0,99, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,64,0,0,0,115,74,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,100, + 8,132,0,90,6,100,9,100,10,132,0,90,7,100,11,100, + 12,156,1,100,13,100,14,132,2,90,8,100,15,100,16,132, + 0,90,9,100,17,83,0,41,18,218,12,83,111,117,114,99, + 101,76,111,97,100,101,114,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,8,0,0,0,116,0,130,1,100,1,83,0,41,2,122, + 165,79,112,116,105,111,110,97,108,32,109,101,116,104,111,100, + 32,116,104,97,116,32,114,101,116,117,114,110,115,32,116,104, + 101,32,109,111,100,105,102,105,99,97,116,105,111,110,32,116, + 105,109,101,32,40,97,110,32,105,110,116,41,32,102,111,114, + 32,116,104,101,10,32,32,32,32,32,32,32,32,115,112,101, + 99,105,102,105,101,100,32,112,97,116,104,32,40,97,32,115, + 116,114,41,46,10,10,32,32,32,32,32,32,32,32,82,97, + 105,115,101,115,32,79,83,69,114,114,111,114,32,119,104,101, + 110,32,116,104,101,32,112,97,116,104,32,99,97,110,110,111, + 116,32,98,101,32,104,97,110,100,108,101,100,46,10,32,32, + 32,32,32,32,32,32,78,41,1,114,50,0,0,0,169,2, + 114,119,0,0,0,114,44,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,10,112,97,116,104,95, + 109,116,105,109,101,24,3,0,0,115,2,0,0,0,0,6, + 122,23,83,111,117,114,99,101,76,111,97,100,101,114,46,112, + 97,116,104,95,109,116,105,109,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,14,0,0,0,100,1,124,0,160,0,124,1,161, + 1,105,1,83,0,41,2,97,158,1,0,0,79,112,116,105, + 111,110,97,108,32,109,101,116,104,111,100,32,114,101,116,117, + 114,110,105,110,103,32,97,32,109,101,116,97,100,97,116,97, + 32,100,105,99,116,32,102,111,114,32,116,104,101,32,115,112, + 101,99,105,102,105,101,100,10,32,32,32,32,32,32,32,32, + 112,97,116,104,32,40,97,32,115,116,114,41,46,10,10,32, + 32,32,32,32,32,32,32,80,111,115,115,105,98,108,101,32, + 107,101,121,115,58,10,32,32,32,32,32,32,32,32,45,32, + 39,109,116,105,109,101,39,32,40,109,97,110,100,97,116,111, + 114,121,41,32,105,115,32,116,104,101,32,110,117,109,101,114, + 105,99,32,116,105,109,101,115,116,97,109,112,32,111,102,32, + 108,97,115,116,32,115,111,117,114,99,101,10,32,32,32,32, + 32,32,32,32,32,32,99,111,100,101,32,109,111,100,105,102, + 105,99,97,116,105,111,110,59,10,32,32,32,32,32,32,32, + 32,45,32,39,115,105,122,101,39,32,40,111,112,116,105,111, + 110,97,108,41,32,105,115,32,116,104,101,32,115,105,122,101, + 32,105,110,32,98,121,116,101,115,32,111,102,32,116,104,101, + 32,115,111,117,114,99,101,32,99,111,100,101,46,10,10,32, + 32,32,32,32,32,32,32,73,109,112,108,101,109,101,110,116, + 105,110,103,32,116,104,105,115,32,109,101,116,104,111,100,32, + 97,108,108,111,119,115,32,116,104,101,32,108,111,97,100,101, + 114,32,116,111,32,114,101,97,100,32,98,121,116,101,99,111, + 100,101,32,102,105,108,101,115,46,10,32,32,32,32,32,32, + 32,32,82,97,105,115,101,115,32,79,83,69,114,114,111,114, + 32,119,104,101,110,32,116,104,101,32,112,97,116,104,32,99, + 97,110,110,111,116,32,98,101,32,104,97,110,100,108,101,100, + 46,10,32,32,32,32,32,32,32,32,114,170,0,0,0,41, + 1,114,224,0,0,0,114,223,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,10,112,97,116,104, + 95,115,116,97,116,115,32,3,0,0,115,2,0,0,0,0, + 12,122,23,83,111,117,114,99,101,76,111,97,100,101,114,46, + 112,97,116,104,95,115,116,97,116,115,99,4,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, + 0,0,0,115,12,0,0,0,124,0,160,0,124,2,124,3, + 161,2,83,0,41,1,122,228,79,112,116,105,111,110,97,108, + 32,109,101,116,104,111,100,32,119,104,105,99,104,32,119,114, + 105,116,101,115,32,100,97,116,97,32,40,98,121,116,101,115, + 41,32,116,111,32,97,32,102,105,108,101,32,112,97,116,104, + 32,40,97,32,115,116,114,41,46,10,10,32,32,32,32,32, + 32,32,32,73,109,112,108,101,109,101,110,116,105,110,103,32, + 116,104,105,115,32,109,101,116,104,111,100,32,97,108,108,111, + 119,115,32,102,111,114,32,116,104,101,32,119,114,105,116,105, + 110,103,32,111,102,32,98,121,116,101,99,111,100,101,32,102, + 105,108,101,115,46,10,10,32,32,32,32,32,32,32,32,84, + 104,101,32,115,111,117,114,99,101,32,112,97,116,104,32,105, + 115,32,110,101,101,100,101,100,32,105,110,32,111,114,100,101, + 114,32,116,111,32,99,111,114,114,101,99,116,108,121,32,116, + 114,97,110,115,102,101,114,32,112,101,114,109,105,115,115,105, + 111,110,115,10,32,32,32,32,32,32,32,32,41,1,218,8, + 115,101,116,95,100,97,116,97,41,4,114,119,0,0,0,114, + 108,0,0,0,90,10,99,97,99,104,101,95,112,97,116,104, + 114,26,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,218,15,95,99,97,99,104,101,95,98,121,116, + 101,99,111,100,101,46,3,0,0,115,2,0,0,0,0,8, + 122,28,83,111,117,114,99,101,76,111,97,100,101,114,46,95, + 99,97,99,104,101,95,98,121,116,101,99,111,100,101,99,3, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,1, + 0,0,0,67,0,0,0,115,4,0,0,0,100,1,83,0, + 41,2,122,150,79,112,116,105,111,110,97,108,32,109,101,116, + 104,111,100,32,119,104,105,99,104,32,119,114,105,116,101,115, + 32,100,97,116,97,32,40,98,121,116,101,115,41,32,116,111, + 32,97,32,102,105,108,101,32,112,97,116,104,32,40,97,32, + 115,116,114,41,46,10,10,32,32,32,32,32,32,32,32,73, + 109,112,108,101,109,101,110,116,105,110,103,32,116,104,105,115, + 32,109,101,116,104,111,100,32,97,108,108,111,119,115,32,102, + 111,114,32,116,104,101,32,119,114,105,116,105,110,103,32,111, + 102,32,98,121,116,101,99,111,100,101,32,102,105,108,101,115, + 46,10,32,32,32,32,32,32,32,32,78,114,3,0,0,0, + 41,3,114,119,0,0,0,114,44,0,0,0,114,26,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,226,0,0,0,56,3,0,0,115,2,0,0,0,0,1, + 122,21,83,111,117,114,99,101,76,111,97,100,101,114,46,115, + 101,116,95,100,97,116,97,99,2,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,10,0,0,0,67,0,0,0, + 115,82,0,0,0,124,0,160,0,124,1,161,1,125,2,122, + 14,124,0,160,1,124,2,161,1,125,3,87,0,110,48,4, + 0,116,2,107,10,114,72,1,0,125,4,1,0,122,18,116, + 3,100,1,124,1,100,2,141,2,124,4,130,2,87,0,53, + 0,100,3,125,4,126,4,88,0,89,0,110,2,88,0,116, + 4,124,3,131,1,83,0,41,4,122,52,67,111,110,99,114, + 101,116,101,32,105,109,112,108,101,109,101,110,116,97,116,105, + 111,110,32,111,102,32,73,110,115,112,101,99,116,76,111,97, + 100,101,114,46,103,101,116,95,115,111,117,114,99,101,46,122, + 39,115,111,117,114,99,101,32,110,111,116,32,97,118,97,105, + 108,97,98,108,101,32,116,104,114,111,117,103,104,32,103,101, + 116,95,100,97,116,97,40,41,114,116,0,0,0,78,41,5, + 114,180,0,0,0,218,8,103,101,116,95,100,97,116,97,114, + 50,0,0,0,114,118,0,0,0,114,177,0,0,0,41,5, + 114,119,0,0,0,114,140,0,0,0,114,44,0,0,0,114, + 175,0,0,0,218,3,101,120,99,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,10,103,101,116,95,115,111, + 117,114,99,101,63,3,0,0,115,20,0,0,0,0,2,10, + 1,2,1,14,1,16,1,4,1,2,255,4,1,2,255,20, + 2,122,23,83,111,117,114,99,101,76,111,97,100,101,114,46, + 103,101,116,95,115,111,117,114,99,101,114,105,0,0,0,41, + 1,218,9,95,111,112,116,105,109,105,122,101,99,3,0,0, + 0,0,0,0,0,1,0,0,0,4,0,0,0,8,0,0, + 0,67,0,0,0,115,22,0,0,0,116,0,106,1,116,2, + 124,1,124,2,100,1,100,2,124,3,100,3,141,6,83,0, + 41,4,122,130,82,101,116,117,114,110,32,116,104,101,32,99, + 111,100,101,32,111,98,106,101,99,116,32,99,111,109,112,105, + 108,101,100,32,102,114,111,109,32,115,111,117,114,99,101,46, + 10,10,32,32,32,32,32,32,32,32,84,104,101,32,39,100, + 97,116,97,39,32,97,114,103,117,109,101,110,116,32,99,97, + 110,32,98,101,32,97,110,121,32,111,98,106,101,99,116,32, + 116,121,112,101,32,116,104,97,116,32,99,111,109,112,105,108, + 101,40,41,32,115,117,112,112,111,114,116,115,46,10,32,32, + 32,32,32,32,32,32,114,216,0,0,0,84,41,2,218,12, + 100,111,110,116,95,105,110,104,101,114,105,116,114,84,0,0, + 0,41,3,114,135,0,0,0,114,215,0,0,0,218,7,99, + 111,109,112,105,108,101,41,4,114,119,0,0,0,114,26,0, + 0,0,114,44,0,0,0,114,231,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,14,115,111,117, + 114,99,101,95,116,111,95,99,111,100,101,73,3,0,0,115, + 8,0,0,0,0,5,12,1,2,0,2,255,122,27,83,111, + 117,114,99,101,76,111,97,100,101,114,46,115,111,117,114,99, + 101,95,116,111,95,99,111,100,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,15,0,0,0,9,0,0,0,67,0, + 0,0,115,34,2,0,0,124,0,160,0,124,1,161,1,125, + 2,100,1,125,3,100,1,125,4,100,1,125,5,100,2,125, + 6,100,3,125,7,122,12,116,1,124,2,131,1,125,8,87, + 0,110,26,4,0,116,2,107,10,114,68,1,0,1,0,1, + 0,100,1,125,8,89,0,144,1,110,48,88,0,122,14,124, + 0,160,3,124,2,161,1,125,9,87,0,110,22,4,0,116, + 4,107,10,114,106,1,0,1,0,1,0,89,0,144,1,110, + 10,88,0,116,5,124,9,100,4,25,0,131,1,125,3,122, + 14,124,0,160,6,124,8,161,1,125,10,87,0,110,20,4, + 0,116,4,107,10,114,154,1,0,1,0,1,0,89,0,110, + 218,88,0,124,1,124,8,100,5,156,2,125,11,122,148,116, + 7,124,10,124,1,124,11,131,3,125,12,116,8,124,10,131, + 1,100,6,100,1,133,2,25,0,125,13,124,12,100,7,64, + 0,100,8,107,3,125,6,124,6,144,1,114,36,124,12,100, + 9,64,0,100,8,107,3,125,7,116,9,106,10,100,10,107, + 3,144,1,114,56,124,7,115,254,116,9,106,10,100,11,107, + 2,144,1,114,56,124,0,160,6,124,2,161,1,125,4,116, + 9,160,11,116,12,124,4,161,2,125,5,116,13,124,10,124, + 5,124,1,124,11,131,4,1,0,110,20,116,14,124,10,124, + 3,124,9,100,12,25,0,124,1,124,11,131,5,1,0,87, + 0,110,26,4,0,116,15,116,16,102,2,107,10,144,1,114, + 84,1,0,1,0,1,0,89,0,110,32,88,0,116,17,160, + 18,100,13,124,8,124,2,161,3,1,0,116,19,124,13,124, + 1,124,8,124,2,100,14,141,4,83,0,124,4,100,1,107, + 8,144,1,114,136,124,0,160,6,124,2,161,1,125,4,124, + 0,160,20,124,4,124,2,161,2,125,14,116,17,160,18,100, + 15,124,2,161,2,1,0,116,21,106,22,144,2,115,30,124, + 8,100,1,107,9,144,2,114,30,124,3,100,1,107,9,144, + 2,114,30,124,6,144,1,114,228,124,5,100,1,107,8,144, + 1,114,214,116,9,160,11,124,4,161,1,125,5,116,23,124, + 14,124,5,124,7,131,3,125,10,110,16,116,24,124,14,124, + 3,116,25,124,4,131,1,131,3,125,10,122,18,124,0,160, + 26,124,2,124,8,124,10,161,3,1,0,87,0,110,22,4, + 0,116,2,107,10,144,2,114,28,1,0,1,0,1,0,89, + 0,110,2,88,0,124,14,83,0,41,16,122,190,67,111,110, + 99,114,101,116,101,32,105,109,112,108,101,109,101,110,116,97, + 116,105,111,110,32,111,102,32,73,110,115,112,101,99,116,76, + 111,97,100,101,114,46,103,101,116,95,99,111,100,101,46,10, + 10,32,32,32,32,32,32,32,32,82,101,97,100,105,110,103, + 32,111,102,32,98,121,116,101,99,111,100,101,32,114,101,113, + 117,105,114,101,115,32,112,97,116,104,95,115,116,97,116,115, + 32,116,111,32,98,101,32,105,109,112,108,101,109,101,110,116, + 101,100,46,32,84,111,32,119,114,105,116,101,10,32,32,32, + 32,32,32,32,32,98,121,116,101,99,111,100,101,44,32,115, + 101,116,95,100,97,116,97,32,109,117,115,116,32,97,108,115, + 111,32,98,101,32,105,109,112,108,101,109,101,110,116,101,100, + 46,10,10,32,32,32,32,32,32,32,32,78,70,84,114,170, + 0,0,0,114,160,0,0,0,114,146,0,0,0,114,39,0, + 0,0,114,73,0,0,0,114,28,0,0,0,90,5,110,101, + 118,101,114,90,6,97,108,119,97,121,115,218,4,115,105,122, + 101,122,13,123,125,32,109,97,116,99,104,101,115,32,123,125, + 41,3,114,117,0,0,0,114,107,0,0,0,114,108,0,0, + 0,122,19,99,111,100,101,32,111,98,106,101,99,116,32,102, + 114,111,109,32,123,125,41,27,114,180,0,0,0,114,98,0, + 0,0,114,82,0,0,0,114,225,0,0,0,114,50,0,0, + 0,114,17,0,0,0,114,228,0,0,0,114,153,0,0,0, + 218,10,109,101,109,111,114,121,118,105,101,119,114,164,0,0, + 0,90,21,99,104,101,99,107,95,104,97,115,104,95,98,97, + 115,101,100,95,112,121,99,115,114,158,0,0,0,218,17,95, + 82,65,87,95,77,65,71,73,67,95,78,85,77,66,69,82, + 114,159,0,0,0,114,157,0,0,0,114,118,0,0,0,114, + 151,0,0,0,114,135,0,0,0,114,150,0,0,0,114,166, + 0,0,0,114,234,0,0,0,114,8,0,0,0,218,19,100, + 111,110,116,95,119,114,105,116,101,95,98,121,116,101,99,111, + 100,101,114,172,0,0,0,114,171,0,0,0,114,22,0,0, + 0,114,227,0,0,0,41,15,114,119,0,0,0,114,140,0, + 0,0,114,108,0,0,0,114,155,0,0,0,114,175,0,0, + 0,114,158,0,0,0,90,10,104,97,115,104,95,98,97,115, + 101,100,90,12,99,104,101,99,107,95,115,111,117,114,99,101, + 114,107,0,0,0,218,2,115,116,114,26,0,0,0,114,152, + 0,0,0,114,83,0,0,0,90,10,98,121,116,101,115,95, + 100,97,116,97,90,11,99,111,100,101,95,111,98,106,101,99, + 116,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,214,0,0,0,81,3,0,0,115,152,0,0,0,0,7, + 10,1,4,1,4,1,4,1,4,1,4,1,2,1,12,1, + 14,1,12,2,2,1,14,1,14,1,8,2,12,1,2,1, + 14,1,14,1,6,3,2,1,2,254,6,4,2,1,12,1, + 16,1,12,1,6,1,12,1,12,1,2,255,2,2,8,254, + 4,3,10,1,4,1,2,1,2,254,4,4,8,1,2,255, + 6,3,2,1,2,1,2,1,6,1,2,1,2,251,8,7, + 20,1,6,2,8,1,2,255,4,2,6,1,2,1,2,254, + 6,3,10,1,10,1,12,1,12,1,18,1,6,255,4,2, + 6,1,10,1,10,1,14,2,6,1,6,255,4,2,2,1, + 18,1,16,1,6,1,122,21,83,111,117,114,99,101,76,111, + 97,100,101,114,46,103,101,116,95,99,111,100,101,78,41,10, + 114,126,0,0,0,114,125,0,0,0,114,127,0,0,0,114, + 224,0,0,0,114,225,0,0,0,114,227,0,0,0,114,226, + 0,0,0,114,230,0,0,0,114,234,0,0,0,114,214,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,222,0,0,0,22,3,0,0,115, + 14,0,0,0,8,2,8,8,8,14,8,10,8,7,8,10, + 14,8,114,222,0,0,0,99,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0, + 115,124,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,101,7,135,0,102,1,100, + 8,100,9,132,8,131,1,90,8,101,7,100,10,100,11,132, + 0,131,1,90,9,100,12,100,13,132,0,90,10,101,7,100, + 14,100,15,132,0,131,1,90,11,100,16,100,17,132,0,90, + 12,100,18,100,19,132,0,90,13,100,20,100,21,132,0,90, + 14,100,22,100,23,132,0,90,15,135,0,4,0,90,16,83, + 0,41,24,218,10,70,105,108,101,76,111,97,100,101,114,122, + 103,66,97,115,101,32,102,105,108,101,32,108,111,97,100,101, + 114,32,99,108,97,115,115,32,119,104,105,99,104,32,105,109, + 112,108,101,109,101,110,116,115,32,116,104,101,32,108,111,97, + 100,101,114,32,112,114,111,116,111,99,111,108,32,109,101,116, + 104,111,100,115,32,116,104,97,116,10,32,32,32,32,114,101, + 113,117,105,114,101,32,102,105,108,101,32,115,121,115,116,101, + 109,32,117,115,97,103,101,46,99,3,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,2,0,0,0,67,0,0, + 0,115,16,0,0,0,124,1,124,0,95,0,124,2,124,0, + 95,1,100,1,83,0,41,2,122,75,67,97,99,104,101,32, + 116,104,101,32,109,111,100,117,108,101,32,110,97,109,101,32, + 97,110,100,32,116,104,101,32,112,97,116,104,32,116,111,32, + 116,104,101,32,102,105,108,101,32,102,111,117,110,100,32,98, + 121,32,116,104,101,10,32,32,32,32,32,32,32,32,102,105, + 110,100,101,114,46,78,114,160,0,0,0,41,3,114,119,0, + 0,0,114,140,0,0,0,114,44,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,210,0,0,0, + 171,3,0,0,115,4,0,0,0,0,3,6,1,122,19,70, + 105,108,101,76,111,97,100,101,114,46,95,95,105,110,105,116, + 95,95,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,24,0,0,0, + 124,0,106,0,124,1,106,0,107,2,111,22,124,0,106,1, + 124,1,106,1,107,2,83,0,114,110,0,0,0,169,2,218, + 9,95,95,99,108,97,115,115,95,95,114,132,0,0,0,169, + 2,114,119,0,0,0,90,5,111,116,104,101,114,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,6,95,95, + 101,113,95,95,177,3,0,0,115,6,0,0,0,0,1,12, + 1,10,255,122,17,70,105,108,101,76,111,97,100,101,114,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, + 20,0,0,0,116,0,124,0,106,1,131,1,116,0,124,0, + 106,2,131,1,65,0,83,0,114,110,0,0,0,169,3,218, + 4,104,97,115,104,114,117,0,0,0,114,44,0,0,0,169, + 1,114,119,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,8,95,95,104,97,115,104,95,95,181, + 3,0,0,115,2,0,0,0,0,1,122,19,70,105,108,101, + 76,111,97,100,101,114,46,95,95,104,97,115,104,95,95,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,6,0,0,0,124,0,106, - 0,83,0,169,1,122,58,82,101,116,117,114,110,32,116,104, - 101,32,112,97,116,104,32,116,111,32,116,104,101,32,115,111, - 117,114,99,101,32,102,105,108,101,32,97,115,32,102,111,117, - 110,100,32,98,121,32,116,104,101,32,102,105,110,100,101,114, - 46,114,48,0,0,0,114,219,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,179,0,0,0,191, - 3,0,0,115,2,0,0,0,0,3,122,23,70,105,108,101, - 76,111,97,100,101,114,46,103,101,116,95,102,105,108,101,110, - 97,109,101,99,2,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,10,0,0,0,67,0,0,0,115,102,0,0, - 0,116,0,124,0,116,1,116,2,102,2,131,2,114,58,116, - 3,160,4,116,5,124,1,131,1,161,1,143,22,125,2,124, - 2,160,6,161,0,87,0,2,0,53,0,81,0,82,0,163, - 0,83,0,81,0,82,0,88,0,110,40,116,3,160,7,124, - 1,100,1,161,2,143,22,125,2,124,2,160,6,161,0,87, - 0,2,0,53,0,81,0,82,0,163,0,83,0,81,0,82, - 0,88,0,100,2,83,0,41,3,122,39,82,101,116,117,114, - 110,32,116,104,101,32,100,97,116,97,32,102,114,111,109,32, - 112,97,116,104,32,97,115,32,114,97,119,32,98,121,116,101, - 115,46,218,1,114,78,41,8,114,161,0,0,0,114,221,0, - 0,0,218,19,69,120,116,101,110,115,105,111,110,70,105,108, - 101,76,111,97,100,101,114,114,64,0,0,0,90,9,111,112, - 101,110,95,99,111,100,101,114,85,0,0,0,90,4,114,101, - 97,100,114,65,0,0,0,41,3,114,119,0,0,0,114,44, - 0,0,0,114,68,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,227,0,0,0,196,3,0,0, - 115,10,0,0,0,0,2,14,1,16,1,28,2,14,1,122, - 19,70,105,108,101,76,111,97,100,101,114,46,103,101,116,95, - 100,97,116,97,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,18,0, - 0,0,124,0,160,0,124,1,161,1,114,14,124,0,83,0, - 100,0,83,0,114,110,0,0,0,41,1,114,182,0,0,0, - 169,2,114,119,0,0,0,114,216,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,19,103,101,116, - 95,114,101,115,111,117,114,99,101,95,114,101,97,100,101,114, - 207,3,0,0,115,6,0,0,0,0,2,10,1,4,1,122, - 30,70,105,108,101,76,111,97,100,101,114,46,103,101,116,95, - 114,101,115,111,117,114,99,101,95,114,101,97,100,101,114,99, - 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, - 4,0,0,0,67,0,0,0,115,32,0,0,0,116,0,116, - 1,124,0,106,2,131,1,100,1,25,0,124,1,131,2,125, - 2,116,3,160,4,124,2,100,2,161,2,83,0,41,3,78, - 114,73,0,0,0,114,251,0,0,0,41,5,114,38,0,0, - 0,114,47,0,0,0,114,44,0,0,0,114,64,0,0,0, - 114,65,0,0,0,169,3,114,119,0,0,0,90,8,114,101, - 115,111,117,114,99,101,114,44,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,13,111,112,101,110, - 95,114,101,115,111,117,114,99,101,213,3,0,0,115,4,0, - 0,0,0,1,20,1,122,24,70,105,108,101,76,111,97,100, - 101,114,46,111,112,101,110,95,114,101,115,111,117,114,99,101, - 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,3,0,0,0,67,0,0,0,115,38,0,0,0,124,0, - 160,0,124,1,161,1,115,14,116,1,130,1,116,2,116,3, - 124,0,106,4,131,1,100,1,25,0,124,1,131,2,125,2, - 124,2,83,0,169,2,78,114,73,0,0,0,41,5,218,11, - 105,115,95,114,101,115,111,117,114,99,101,218,17,70,105,108, - 101,78,111,116,70,111,117,110,100,69,114,114,111,114,114,38, - 0,0,0,114,47,0,0,0,114,44,0,0,0,114,255,0, + 3,0,0,0,3,0,0,0,115,16,0,0,0,116,0,116, + 1,124,0,131,2,160,2,124,1,161,1,83,0,41,1,122, + 100,76,111,97,100,32,97,32,109,111,100,117,108,101,32,102, + 114,111,109,32,97,32,102,105,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,3,218,5,115,117,112,101,114,114,240, + 0,0,0,114,221,0,0,0,114,220,0,0,0,169,1,114, + 242,0,0,0,114,3,0,0,0,114,6,0,0,0,114,221, + 0,0,0,184,3,0,0,115,2,0,0,0,0,10,122,22, + 70,105,108,101,76,111,97,100,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,1,0,0,0,67,0,0,0,115, + 6,0,0,0,124,0,106,0,83,0,169,1,122,58,82,101, + 116,117,114,110,32,116,104,101,32,112,97,116,104,32,116,111, + 32,116,104,101,32,115,111,117,114,99,101,32,102,105,108,101, + 32,97,115,32,102,111,117,110,100,32,98,121,32,116,104,101, + 32,102,105,110,100,101,114,46,114,48,0,0,0,114,220,0, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,13,114,101,115,111,117,114,99,101,95,112,97,116,104, - 217,3,0,0,115,8,0,0,0,0,1,10,1,4,1,20, - 1,122,24,70,105,108,101,76,111,97,100,101,114,46,114,101, - 115,111,117,114,99,101,95,112,97,116,104,99,2,0,0,0, - 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, - 67,0,0,0,115,40,0,0,0,116,0,124,1,107,6,114, - 12,100,1,83,0,116,1,116,2,124,0,106,3,131,1,100, - 2,25,0,124,1,131,2,125,2,116,4,124,2,131,1,83, - 0,41,3,78,70,114,73,0,0,0,41,5,114,35,0,0, - 0,114,38,0,0,0,114,47,0,0,0,114,44,0,0,0, - 114,54,0,0,0,169,3,114,119,0,0,0,114,117,0,0, - 0,114,44,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,2,1,0,0,223,3,0,0,115,8, - 0,0,0,0,1,8,1,4,1,20,1,122,22,70,105,108, - 101,76,111,97,100,101,114,46,105,115,95,114,101,115,111,117, - 114,99,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,24,0,0, - 0,116,0,116,1,160,2,116,3,124,0,106,4,131,1,100, - 1,25,0,161,1,131,1,83,0,114,1,1,0,0,41,5, - 218,4,105,116,101,114,114,2,0,0,0,218,7,108,105,115, - 116,100,105,114,114,47,0,0,0,114,44,0,0,0,114,246, + 0,114,180,0,0,0,196,3,0,0,115,2,0,0,0,0, + 3,122,23,70,105,108,101,76,111,97,100,101,114,46,103,101, + 116,95,102,105,108,101,110,97,109,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,10,0,0,0,67, + 0,0,0,115,102,0,0,0,116,0,124,0,116,1,116,2, + 102,2,131,2,114,58,116,3,160,4,116,5,124,1,131,1, + 161,1,143,22,125,2,124,2,160,6,161,0,87,0,2,0, + 53,0,81,0,82,0,163,0,83,0,81,0,82,0,88,0, + 110,40,116,3,160,7,124,1,100,1,161,2,143,22,125,2, + 124,2,160,6,161,0,87,0,2,0,53,0,81,0,82,0, + 163,0,83,0,81,0,82,0,88,0,100,2,83,0,41,3, + 122,39,82,101,116,117,114,110,32,116,104,101,32,100,97,116, + 97,32,102,114,111,109,32,112,97,116,104,32,97,115,32,114, + 97,119,32,98,121,116,101,115,46,218,1,114,78,41,8,114, + 162,0,0,0,114,222,0,0,0,218,19,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,101,114,114,64, + 0,0,0,90,9,111,112,101,110,95,99,111,100,101,114,85, + 0,0,0,90,4,114,101,97,100,114,65,0,0,0,41,3, + 114,119,0,0,0,114,44,0,0,0,114,68,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,228, + 0,0,0,201,3,0,0,115,10,0,0,0,0,2,14,1, + 16,1,28,2,14,1,122,19,70,105,108,101,76,111,97,100, + 101,114,46,103,101,116,95,100,97,116,97,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,18,0,0,0,124,0,160,0,124,1,161, + 1,114,14,124,0,83,0,100,0,83,0,114,110,0,0,0, + 41,1,114,183,0,0,0,169,2,114,119,0,0,0,114,217, 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,8,99,111,110,116,101,110,116,115,229,3,0,0, - 115,2,0,0,0,0,1,122,19,70,105,108,101,76,111,97, - 100,101,114,46,99,111,110,116,101,110,116,115,41,17,114,125, - 0,0,0,114,124,0,0,0,114,126,0,0,0,114,127,0, - 0,0,114,209,0,0,0,114,243,0,0,0,114,247,0,0, - 0,114,136,0,0,0,114,220,0,0,0,114,179,0,0,0, - 114,227,0,0,0,114,254,0,0,0,114,0,1,0,0,114, - 4,1,0,0,114,2,1,0,0,114,8,1,0,0,90,13, - 95,95,99,108,97,115,115,99,101,108,108,95,95,114,3,0, - 0,0,114,3,0,0,0,114,249,0,0,0,114,6,0,0, - 0,114,239,0,0,0,161,3,0,0,115,30,0,0,0,8, - 2,4,3,8,6,8,4,8,3,2,1,14,11,2,1,10, - 4,8,11,2,1,10,5,8,4,8,6,8,6,114,239,0, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,64,0,0,0,115,46,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, - 156,1,100,8,100,9,132,2,90,6,100,10,83,0,41,11, - 218,16,83,111,117,114,99,101,70,105,108,101,76,111,97,100, - 101,114,122,62,67,111,110,99,114,101,116,101,32,105,109,112, - 108,101,109,101,110,116,97,116,105,111,110,32,111,102,32,83, - 111,117,114,99,101,76,111,97,100,101,114,32,117,115,105,110, - 103,32,116,104,101,32,102,105,108,101,32,115,121,115,116,101, - 109,46,99,2,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,3,0,0,0,67,0,0,0,115,22,0,0,0, - 116,0,124,1,131,1,125,2,124,2,106,1,124,2,106,2, - 100,1,156,2,83,0,41,2,122,33,82,101,116,117,114,110, - 32,116,104,101,32,109,101,116,97,100,97,116,97,32,102,111, - 114,32,116,104,101,32,112,97,116,104,46,41,2,114,169,0, - 0,0,114,234,0,0,0,41,3,114,49,0,0,0,218,8, - 115,116,95,109,116,105,109,101,90,7,115,116,95,115,105,122, - 101,41,3,114,119,0,0,0,114,44,0,0,0,114,238,0, + 0,0,218,19,103,101,116,95,114,101,115,111,117,114,99,101, + 95,114,101,97,100,101,114,212,3,0,0,115,6,0,0,0, + 0,2,10,1,4,1,122,30,70,105,108,101,76,111,97,100, + 101,114,46,103,101,116,95,114,101,115,111,117,114,99,101,95, + 114,101,97,100,101,114,99,2,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,4,0,0,0,67,0,0,0,115, + 32,0,0,0,116,0,116,1,124,0,106,2,131,1,100,1, + 25,0,124,1,131,2,125,2,116,3,160,4,124,2,100,2, + 161,2,83,0,41,3,78,114,73,0,0,0,114,252,0,0, + 0,41,5,114,38,0,0,0,114,47,0,0,0,114,44,0, + 0,0,114,64,0,0,0,114,65,0,0,0,169,3,114,119, + 0,0,0,90,8,114,101,115,111,117,114,99,101,114,44,0, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,224,0,0,0,237,3,0,0,115,4,0,0,0,0, - 2,8,1,122,27,83,111,117,114,99,101,70,105,108,101,76, - 111,97,100,101,114,46,112,97,116,104,95,115,116,97,116,115, - 99,4,0,0,0,0,0,0,0,0,0,0,0,5,0,0, - 0,5,0,0,0,67,0,0,0,115,24,0,0,0,116,0, - 124,1,131,1,125,4,124,0,106,1,124,2,124,3,124,4, - 100,1,141,3,83,0,41,2,78,169,1,218,5,95,109,111, - 100,101,41,2,114,115,0,0,0,114,225,0,0,0,41,5, - 114,119,0,0,0,114,108,0,0,0,114,107,0,0,0,114, - 26,0,0,0,114,52,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,226,0,0,0,242,3,0, - 0,115,4,0,0,0,0,2,8,1,122,32,83,111,117,114, - 99,101,70,105,108,101,76,111,97,100,101,114,46,95,99,97, - 99,104,101,95,98,121,116,101,99,111,100,101,114,60,0,0, - 0,114,11,1,0,0,99,3,0,0,0,0,0,0,0,1, - 0,0,0,9,0,0,0,11,0,0,0,67,0,0,0,115, - 0,1,0,0,116,0,124,1,131,1,92,2,125,4,125,5, - 103,0,125,6,124,4,114,52,116,1,124,4,131,1,115,52, - 116,0,124,4,131,1,92,2,125,4,125,7,124,6,160,2, - 124,7,161,1,1,0,113,16,116,3,124,6,131,1,68,0, - 93,112,125,7,116,4,124,4,124,7,131,2,125,4,122,14, - 116,5,160,6,124,4,161,1,1,0,87,0,110,82,4,0, - 116,7,107,10,114,112,1,0,1,0,1,0,89,0,113,60, - 89,0,110,60,4,0,116,8,107,10,114,170,1,0,125,8, - 1,0,122,30,116,9,160,10,100,1,124,4,124,8,161,3, - 1,0,87,0,89,0,162,10,1,0,100,2,83,0,87,0, - 53,0,100,2,125,8,126,8,88,0,89,0,110,2,88,0, - 113,60,122,28,116,11,124,1,124,2,124,3,131,3,1,0, - 116,9,160,10,100,3,124,1,161,2,1,0,87,0,110,48, - 4,0,116,8,107,10,114,250,1,0,125,8,1,0,122,18, - 116,9,160,10,100,1,124,1,124,8,161,3,1,0,87,0, - 53,0,100,2,125,8,126,8,88,0,89,0,110,2,88,0, - 100,2,83,0,41,4,122,27,87,114,105,116,101,32,98,121, - 116,101,115,32,100,97,116,97,32,116,111,32,97,32,102,105, - 108,101,46,122,27,99,111,117,108,100,32,110,111,116,32,99, - 114,101,97,116,101,32,123,33,114,125,58,32,123,33,114,125, - 78,122,12,99,114,101,97,116,101,100,32,123,33,114,125,41, - 12,114,47,0,0,0,114,56,0,0,0,114,186,0,0,0, - 114,42,0,0,0,114,38,0,0,0,114,2,0,0,0,90, - 5,109,107,100,105,114,218,15,70,105,108,101,69,120,105,115, - 116,115,69,114,114,111,114,114,50,0,0,0,114,134,0,0, - 0,114,149,0,0,0,114,69,0,0,0,41,9,114,119,0, - 0,0,114,44,0,0,0,114,26,0,0,0,114,12,1,0, - 0,218,6,112,97,114,101,110,116,114,97,0,0,0,114,37, - 0,0,0,114,33,0,0,0,114,228,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,225,0,0, - 0,247,3,0,0,115,48,0,0,0,0,2,12,1,4,2, - 12,1,12,1,12,2,12,1,10,1,2,1,14,1,14,2, - 8,1,16,3,6,1,2,0,2,255,4,2,32,1,2,1, - 12,1,16,1,16,2,8,1,2,255,122,25,83,111,117,114, - 99,101,70,105,108,101,76,111,97,100,101,114,46,115,101,116, - 95,100,97,116,97,78,41,7,114,125,0,0,0,114,124,0, - 0,0,114,126,0,0,0,114,127,0,0,0,114,224,0,0, - 0,114,226,0,0,0,114,225,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 9,1,0,0,233,3,0,0,115,8,0,0,0,8,2,4, - 2,8,5,8,5,114,9,1,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,20,83,111,117,114, - 99,101,108,101,115,115,70,105,108,101,76,111,97,100,101,114, - 122,45,76,111,97,100,101,114,32,119,104,105,99,104,32,104, - 97,110,100,108,101,115,32,115,111,117,114,99,101,108,101,115, - 115,32,102,105,108,101,32,105,109,112,111,114,116,115,46,99, - 2,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, - 5,0,0,0,67,0,0,0,115,68,0,0,0,124,0,160, - 0,124,1,161,1,125,2,124,0,160,1,124,2,161,1,125, - 3,124,1,124,2,100,1,156,2,125,4,116,2,124,3,124, - 1,124,4,131,3,1,0,116,3,116,4,124,3,131,1,100, - 2,100,0,133,2,25,0,124,1,124,2,100,3,141,3,83, - 0,41,4,78,114,159,0,0,0,114,145,0,0,0,41,2, - 114,117,0,0,0,114,107,0,0,0,41,5,114,179,0,0, - 0,114,227,0,0,0,114,152,0,0,0,114,165,0,0,0, - 114,235,0,0,0,41,5,114,119,0,0,0,114,139,0,0, - 0,114,44,0,0,0,114,26,0,0,0,114,151,0,0,0, + 0,218,13,111,112,101,110,95,114,101,115,111,117,114,99,101, + 218,3,0,0,115,4,0,0,0,0,1,20,1,122,24,70, + 105,108,101,76,111,97,100,101,114,46,111,112,101,110,95,114, + 101,115,111,117,114,99,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,3,0,0,0,67,0,0,0, + 115,38,0,0,0,124,0,160,0,124,1,161,1,115,14,116, + 1,130,1,116,2,116,3,124,0,106,4,131,1,100,1,25, + 0,124,1,131,2,125,2,124,2,83,0,169,2,78,114,73, + 0,0,0,41,5,218,11,105,115,95,114,101,115,111,117,114, + 99,101,218,17,70,105,108,101,78,111,116,70,111,117,110,100, + 69,114,114,111,114,114,38,0,0,0,114,47,0,0,0,114, + 44,0,0,0,114,0,1,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,13,114,101,115,111,117,114, + 99,101,95,112,97,116,104,222,3,0,0,115,8,0,0,0, + 0,1,10,1,4,1,20,1,122,24,70,105,108,101,76,111, + 97,100,101,114,46,114,101,115,111,117,114,99,101,95,112,97, + 116,104,99,2,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,3,0,0,0,67,0,0,0,115,40,0,0,0, + 116,0,124,1,107,6,114,12,100,1,83,0,116,1,116,2, + 124,0,106,3,131,1,100,2,25,0,124,1,131,2,125,2, + 116,4,124,2,131,1,83,0,41,3,78,70,114,73,0,0, + 0,41,5,114,35,0,0,0,114,38,0,0,0,114,47,0, + 0,0,114,44,0,0,0,114,54,0,0,0,169,3,114,119, + 0,0,0,114,117,0,0,0,114,44,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,3,1,0, + 0,228,3,0,0,115,8,0,0,0,0,1,8,1,4,1, + 20,1,122,22,70,105,108,101,76,111,97,100,101,114,46,105, + 115,95,114,101,115,111,117,114,99,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,24,0,0,0,116,0,116,1,160,2,116,3, + 124,0,106,4,131,1,100,1,25,0,161,1,131,1,83,0, + 114,2,1,0,0,41,5,218,4,105,116,101,114,114,2,0, + 0,0,218,7,108,105,115,116,100,105,114,114,47,0,0,0, + 114,44,0,0,0,114,247,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,8,99,111,110,116,101, + 110,116,115,234,3,0,0,115,2,0,0,0,0,1,122,19, + 70,105,108,101,76,111,97,100,101,114,46,99,111,110,116,101, + 110,116,115,41,17,114,126,0,0,0,114,125,0,0,0,114, + 127,0,0,0,114,128,0,0,0,114,210,0,0,0,114,244, + 0,0,0,114,248,0,0,0,114,137,0,0,0,114,221,0, + 0,0,114,180,0,0,0,114,228,0,0,0,114,255,0,0, + 0,114,1,1,0,0,114,5,1,0,0,114,3,1,0,0, + 114,9,1,0,0,90,13,95,95,99,108,97,115,115,99,101, + 108,108,95,95,114,3,0,0,0,114,3,0,0,0,114,250, + 0,0,0,114,6,0,0,0,114,240,0,0,0,166,3,0, + 0,115,30,0,0,0,8,2,4,3,8,6,8,4,8,3, + 2,1,14,11,2,1,10,4,8,11,2,1,10,5,8,4, + 8,6,8,6,114,240,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,64,0, + 0,0,115,46,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,156,1,100,8,100,9,132,2,90, + 6,100,10,83,0,41,11,218,16,83,111,117,114,99,101,70, + 105,108,101,76,111,97,100,101,114,122,62,67,111,110,99,114, + 101,116,101,32,105,109,112,108,101,109,101,110,116,97,116,105, + 111,110,32,111,102,32,83,111,117,114,99,101,76,111,97,100, + 101,114,32,117,115,105,110,103,32,116,104,101,32,102,105,108, + 101,32,115,121,115,116,101,109,46,99,2,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,3,0,0,0,67,0, + 0,0,115,22,0,0,0,116,0,124,1,131,1,125,2,124, + 2,106,1,124,2,106,2,100,1,156,2,83,0,41,2,122, + 33,82,101,116,117,114,110,32,116,104,101,32,109,101,116,97, + 100,97,116,97,32,102,111,114,32,116,104,101,32,112,97,116, + 104,46,41,2,114,170,0,0,0,114,235,0,0,0,41,3, + 114,49,0,0,0,218,8,115,116,95,109,116,105,109,101,90, + 7,115,116,95,115,105,122,101,41,3,114,119,0,0,0,114, + 44,0,0,0,114,239,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,225,0,0,0,242,3,0, + 0,115,4,0,0,0,0,2,8,1,122,27,83,111,117,114, + 99,101,70,105,108,101,76,111,97,100,101,114,46,112,97,116, + 104,95,115,116,97,116,115,99,4,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, + 115,24,0,0,0,116,0,124,1,131,1,125,4,124,0,106, + 1,124,2,124,3,124,4,100,1,141,3,83,0,41,2,78, + 169,1,218,5,95,109,111,100,101,41,2,114,115,0,0,0, + 114,226,0,0,0,41,5,114,119,0,0,0,114,108,0,0, + 0,114,107,0,0,0,114,26,0,0,0,114,52,0,0,0, 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 213,0,0,0,26,4,0,0,115,22,0,0,0,0,1,10, - 1,10,4,2,1,2,254,6,4,12,1,2,1,14,1,2, - 1,2,253,122,29,83,111,117,114,99,101,108,101,115,115,70, - 105,108,101,76,111,97,100,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,39,82,101,116,117,114,110,32,78, - 111,110,101,32,97,115,32,116,104,101,114,101,32,105,115,32, - 110,111,32,115,111,117,114,99,101,32,99,111,100,101,46,78, - 114,3,0,0,0,114,219,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,229,0,0,0,42,4, - 0,0,115,2,0,0,0,0,2,122,31,83,111,117,114,99, - 101,108,101,115,115,70,105,108,101,76,111,97,100,101,114,46, - 103,101,116,95,115,111,117,114,99,101,78,41,6,114,125,0, - 0,0,114,124,0,0,0,114,126,0,0,0,114,127,0,0, - 0,114,213,0,0,0,114,229,0,0,0,114,3,0,0,0, + 227,0,0,0,247,3,0,0,115,4,0,0,0,0,2,8, + 1,122,32,83,111,117,114,99,101,70,105,108,101,76,111,97, + 100,101,114,46,95,99,97,99,104,101,95,98,121,116,101,99, + 111,100,101,114,60,0,0,0,114,12,1,0,0,99,3,0, + 0,0,0,0,0,0,1,0,0,0,9,0,0,0,11,0, + 0,0,67,0,0,0,115,252,0,0,0,116,0,124,1,131, + 1,92,2,125,4,125,5,103,0,125,6,124,4,114,52,116, + 1,124,4,131,1,115,52,116,0,124,4,131,1,92,2,125, + 4,125,7,124,6,160,2,124,7,161,1,1,0,113,16,116, + 3,124,6,131,1,68,0,93,108,125,7,116,4,124,4,124, + 7,131,2,125,4,122,14,116,5,160,6,124,4,161,1,1, + 0,87,0,113,60,4,0,116,7,107,10,114,112,1,0,1, + 0,1,0,89,0,113,60,89,0,113,60,4,0,116,8,107, + 10,114,166,1,0,125,8,1,0,122,26,116,9,160,10,100, + 1,124,4,124,8,161,3,1,0,87,0,89,0,162,6,1, + 0,100,2,83,0,100,2,125,8,126,8,88,0,89,0,113, + 60,88,0,113,60,122,28,116,11,124,1,124,2,124,3,131, + 3,1,0,116,9,160,10,100,3,124,1,161,2,1,0,87, + 0,110,48,4,0,116,8,107,10,114,246,1,0,125,8,1, + 0,122,18,116,9,160,10,100,1,124,1,124,8,161,3,1, + 0,87,0,53,0,100,2,125,8,126,8,88,0,89,0,110, + 2,88,0,100,2,83,0,41,4,122,27,87,114,105,116,101, + 32,98,121,116,101,115,32,100,97,116,97,32,116,111,32,97, + 32,102,105,108,101,46,122,27,99,111,117,108,100,32,110,111, + 116,32,99,114,101,97,116,101,32,123,33,114,125,58,32,123, + 33,114,125,78,122,12,99,114,101,97,116,101,100,32,123,33, + 114,125,41,12,114,47,0,0,0,114,56,0,0,0,114,187, + 0,0,0,114,42,0,0,0,114,38,0,0,0,114,2,0, + 0,0,90,5,109,107,100,105,114,218,15,70,105,108,101,69, + 120,105,115,116,115,69,114,114,111,114,114,50,0,0,0,114, + 135,0,0,0,114,150,0,0,0,114,69,0,0,0,41,9, + 114,119,0,0,0,114,44,0,0,0,114,26,0,0,0,114, + 13,1,0,0,218,6,112,97,114,101,110,116,114,97,0,0, + 0,114,37,0,0,0,114,33,0,0,0,114,229,0,0,0, 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 15,1,0,0,22,4,0,0,115,6,0,0,0,8,2,4, - 2,8,16,114,15,1,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, - 0,115,92,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,100,13,132,0, - 90,9,100,14,100,15,132,0,90,10,100,16,100,17,132,0, - 90,11,101,12,100,18,100,19,132,0,131,1,90,13,100,20, - 83,0,41,21,114,252,0,0,0,122,93,76,111,97,100,101, - 114,32,102,111,114,32,101,120,116,101,110,115,105,111,110,32, - 109,111,100,117,108,101,115,46,10,10,32,32,32,32,84,104, - 101,32,99,111,110,115,116,114,117,99,116,111,114,32,105,115, - 32,100,101,115,105,103,110,101,100,32,116,111,32,119,111,114, - 107,32,119,105,116,104,32,70,105,108,101,70,105,110,100,101, - 114,46,10,10,32,32,32,32,99,3,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,2,0,0,0,67,0,0, - 0,115,16,0,0,0,124,1,124,0,95,0,124,2,124,0, - 95,1,100,0,83,0,114,110,0,0,0,114,159,0,0,0, - 114,5,1,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,209,0,0,0,59,4,0,0,115,4,0, - 0,0,0,1,6,1,122,28,69,120,116,101,110,115,105,111, - 110,70,105,108,101,76,111,97,100,101,114,46,95,95,105,110, - 105,116,95,95,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,24,0, - 0,0,124,0,106,0,124,1,106,0,107,2,111,22,124,0, - 106,1,124,1,106,1,107,2,83,0,114,110,0,0,0,114, - 240,0,0,0,114,242,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,243,0,0,0,63,4,0, - 0,115,6,0,0,0,0,1,12,1,10,255,122,26,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,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,20,0,0,0,116,0,124,0,106,1,131,1,116,0, - 124,0,106,2,131,1,65,0,83,0,114,110,0,0,0,114, - 244,0,0,0,114,246,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,247,0,0,0,67,4,0, - 0,115,2,0,0,0,0,1,122,28,69,120,116,101,110,115, - 105,111,110,70,105,108,101,76,111,97,100,101,114,46,95,95, - 104,97,115,104,95,95,99,2,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,5,0,0,0,67,0,0,0,115, - 36,0,0,0,116,0,160,1,116,2,106,3,124,1,161,2, - 125,2,116,0,160,4,100,1,124,1,106,5,124,0,106,6, - 161,3,1,0,124,2,83,0,41,2,122,38,67,114,101,97, - 116,101,32,97,110,32,117,110,105,116,105,97,108,105,122,101, - 100,32,101,120,116,101,110,115,105,111,110,32,109,111,100,117, - 108,101,122,38,101,120,116,101,110,115,105,111,110,32,109,111, - 100,117,108,101,32,123,33,114,125,32,108,111,97,100,101,100, - 32,102,114,111,109,32,123,33,114,125,41,7,114,134,0,0, - 0,114,214,0,0,0,114,163,0,0,0,90,14,99,114,101, - 97,116,101,95,100,121,110,97,109,105,99,114,149,0,0,0, - 114,117,0,0,0,114,44,0,0,0,41,3,114,119,0,0, - 0,114,187,0,0,0,114,216,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,212,0,0,0,70, - 4,0,0,115,18,0,0,0,0,2,4,1,4,0,2,255, - 4,2,6,1,4,0,4,255,4,2,122,33,69,120,116,101, - 110,115,105,111,110,70,105,108,101,76,111,97,100,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,5,0, - 0,0,67,0,0,0,115,36,0,0,0,116,0,160,1,116, - 2,106,3,124,1,161,2,1,0,116,0,160,4,100,1,124, - 0,106,5,124,0,106,6,161,3,1,0,100,2,83,0,41, - 3,122,30,73,110,105,116,105,97,108,105,122,101,32,97,110, - 32,101,120,116,101,110,115,105,111,110,32,109,111,100,117,108, - 101,122,40,101,120,116,101,110,115,105,111,110,32,109,111,100, - 117,108,101,32,123,33,114,125,32,101,120,101,99,117,116,101, - 100,32,102,114,111,109,32,123,33,114,125,78,41,7,114,134, - 0,0,0,114,214,0,0,0,114,163,0,0,0,90,12,101, - 120,101,99,95,100,121,110,97,109,105,99,114,149,0,0,0, - 114,117,0,0,0,114,44,0,0,0,114,253,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,217, - 0,0,0,78,4,0,0,115,10,0,0,0,0,2,14,1, - 6,1,4,0,4,255,122,31,69,120,116,101,110,115,105,111, - 110,70,105,108,101,76,111,97,100,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,4,0,0,0,3,0,0,0, - 115,36,0,0,0,116,0,124,0,106,1,131,1,100,1,25, - 0,137,0,116,2,135,0,102,1,100,2,100,3,132,8,116, - 3,68,0,131,1,131,1,83,0,41,4,122,49,82,101,116, - 117,114,110,32,84,114,117,101,32,105,102,32,116,104,101,32, - 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, - 32,105,115,32,97,32,112,97,99,107,97,103,101,46,114,39, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,4,0,0,0,51,0,0,0,115,26,0,0, - 0,124,0,93,18,125,1,136,0,100,0,124,1,23,0,107, - 2,86,0,1,0,113,2,100,1,83,0,41,2,114,209,0, - 0,0,78,114,3,0,0,0,169,2,114,32,0,0,0,218, - 6,115,117,102,102,105,120,169,1,90,9,102,105,108,101,95, - 110,97,109,101,114,3,0,0,0,114,6,0,0,0,218,9, - 60,103,101,110,101,120,112,114,62,87,4,0,0,115,4,0, - 0,0,4,1,2,255,122,49,69,120,116,101,110,115,105,111, - 110,70,105,108,101,76,111,97,100,101,114,46,105,115,95,112, - 97,99,107,97,103,101,46,60,108,111,99,97,108,115,62,46, - 60,103,101,110,101,120,112,114,62,41,4,114,47,0,0,0, - 114,44,0,0,0,218,3,97,110,121,218,18,69,88,84,69, - 78,83,73,79,78,95,83,85,70,70,73,88,69,83,114,219, - 0,0,0,114,3,0,0,0,114,18,1,0,0,114,6,0, - 0,0,114,182,0,0,0,84,4,0,0,115,8,0,0,0, - 0,2,14,1,12,1,2,255,122,30,69,120,116,101,110,115, - 105,111,110,70,105,108,101,76,111,97,100,101,114,46,105,115, - 95,112,97,99,107,97,103,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,63,82,101, - 116,117,114,110,32,78,111,110,101,32,97,115,32,97,110,32, - 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, - 32,99,97,110,110,111,116,32,99,114,101,97,116,101,32,97, - 32,99,111,100,101,32,111,98,106,101,99,116,46,78,114,3, - 0,0,0,114,219,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,213,0,0,0,90,4,0,0, - 115,2,0,0,0,0,2,122,28,69,120,116,101,110,115,105, - 111,110,70,105,108,101,76,111,97,100,101,114,46,103,101,116, + 226,0,0,0,252,3,0,0,115,48,0,0,0,0,2,12, + 1,4,2,12,1,12,1,12,2,12,1,10,1,2,1,14, + 1,14,2,8,1,16,3,6,1,2,0,2,255,4,2,28, + 1,2,1,12,1,16,1,16,2,8,1,2,255,122,25,83, + 111,117,114,99,101,70,105,108,101,76,111,97,100,101,114,46, + 115,101,116,95,100,97,116,97,78,41,7,114,126,0,0,0, + 114,125,0,0,0,114,127,0,0,0,114,128,0,0,0,114, + 225,0,0,0,114,227,0,0,0,114,226,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,10,1,0,0,238,3,0,0,115,8,0,0,0, + 8,2,4,2,8,5,8,5,114,10,1,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,20,83, + 111,117,114,99,101,108,101,115,115,70,105,108,101,76,111,97, + 100,101,114,122,45,76,111,97,100,101,114,32,119,104,105,99, + 104,32,104,97,110,100,108,101,115,32,115,111,117,114,99,101, + 108,101,115,115,32,102,105,108,101,32,105,109,112,111,114,116, + 115,46,99,2,0,0,0,0,0,0,0,0,0,0,0,5, + 0,0,0,5,0,0,0,67,0,0,0,115,68,0,0,0, + 124,0,160,0,124,1,161,1,125,2,124,0,160,1,124,2, + 161,1,125,3,124,1,124,2,100,1,156,2,125,4,116,2, + 124,3,124,1,124,4,131,3,1,0,116,3,116,4,124,3, + 131,1,100,2,100,0,133,2,25,0,124,1,124,2,100,3, + 141,3,83,0,41,4,78,114,160,0,0,0,114,146,0,0, + 0,41,2,114,117,0,0,0,114,107,0,0,0,41,5,114, + 180,0,0,0,114,228,0,0,0,114,153,0,0,0,114,166, + 0,0,0,114,236,0,0,0,41,5,114,119,0,0,0,114, + 140,0,0,0,114,44,0,0,0,114,26,0,0,0,114,152, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,214,0,0,0,31,4,0,0,115,22,0,0,0, + 0,1,10,1,10,4,2,1,2,254,6,4,12,1,2,1, + 14,1,2,1,2,253,122,29,83,111,117,114,99,101,108,101, + 115,115,70,105,108,101,76,111,97,100,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,53,82,101,116,117,114, - 110,32,78,111,110,101,32,97,115,32,101,120,116,101,110,115, - 105,111,110,32,109,111,100,117,108,101,115,32,104,97,118,101, - 32,110,111,32,115,111,117,114,99,101,32,99,111,100,101,46, - 78,114,3,0,0,0,114,219,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,229,0,0,0,94, - 4,0,0,115,2,0,0,0,0,2,122,30,69,120,116,101, + 0,0,0,100,1,83,0,41,2,122,39,82,101,116,117,114, + 110,32,78,111,110,101,32,97,115,32,116,104,101,114,101,32, + 105,115,32,110,111,32,115,111,117,114,99,101,32,99,111,100, + 101,46,78,114,3,0,0,0,114,220,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,230,0,0, + 0,47,4,0,0,115,2,0,0,0,0,2,122,31,83,111, + 117,114,99,101,108,101,115,115,70,105,108,101,76,111,97,100, + 101,114,46,103,101,116,95,115,111,117,114,99,101,78,41,6, + 114,126,0,0,0,114,125,0,0,0,114,127,0,0,0,114, + 128,0,0,0,114,214,0,0,0,114,230,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,16,1,0,0,27,4,0,0,115,6,0,0,0, + 8,2,4,2,8,16,114,16,1,0,0,99,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 64,0,0,0,115,92,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,100, + 13,132,0,90,9,100,14,100,15,132,0,90,10,100,16,100, + 17,132,0,90,11,101,12,100,18,100,19,132,0,131,1,90, + 13,100,20,83,0,41,21,114,253,0,0,0,122,93,76,111, + 97,100,101,114,32,102,111,114,32,101,120,116,101,110,115,105, + 111,110,32,109,111,100,117,108,101,115,46,10,10,32,32,32, + 32,84,104,101,32,99,111,110,115,116,114,117,99,116,111,114, + 32,105,115,32,100,101,115,105,103,110,101,100,32,116,111,32, + 119,111,114,107,32,119,105,116,104,32,70,105,108,101,70,105, + 110,100,101,114,46,10,10,32,32,32,32,99,3,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0, + 67,0,0,0,115,16,0,0,0,124,1,124,0,95,0,124, + 2,124,0,95,1,100,0,83,0,114,110,0,0,0,114,160, + 0,0,0,114,6,1,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,210,0,0,0,64,4,0,0, + 115,4,0,0,0,0,1,6,1,122,28,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,95, + 95,105,110,105,116,95,95,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,24,0,0,0,124,0,106,0,124,1,106,0,107,2,111, + 22,124,0,106,1,124,1,106,1,107,2,83,0,114,110,0, + 0,0,114,241,0,0,0,114,243,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,244,0,0,0, + 68,4,0,0,115,6,0,0,0,0,1,12,1,10,255,122, + 26,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, + 97,100,101,114,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,20,0,0,0,116,0,124,0,106,1,131, + 1,116,0,124,0,106,2,131,1,65,0,83,0,114,110,0, + 0,0,114,245,0,0,0,114,247,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,248,0,0,0, + 72,4,0,0,115,2,0,0,0,0,1,122,28,69,120,116, + 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, + 46,95,95,104,97,115,104,95,95,99,2,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,5,0,0,0,67,0, + 0,0,115,36,0,0,0,116,0,160,1,116,2,106,3,124, + 1,161,2,125,2,116,0,160,4,100,1,124,1,106,5,124, + 0,106,6,161,3,1,0,124,2,83,0,41,2,122,38,67, + 114,101,97,116,101,32,97,110,32,117,110,105,116,105,97,108, + 105,122,101,100,32,101,120,116,101,110,115,105,111,110,32,109, + 111,100,117,108,101,122,38,101,120,116,101,110,115,105,111,110, + 32,109,111,100,117,108,101,32,123,33,114,125,32,108,111,97, + 100,101,100,32,102,114,111,109,32,123,33,114,125,41,7,114, + 135,0,0,0,114,215,0,0,0,114,164,0,0,0,90,14, + 99,114,101,97,116,101,95,100,121,110,97,109,105,99,114,150, + 0,0,0,114,117,0,0,0,114,44,0,0,0,41,3,114, + 119,0,0,0,114,188,0,0,0,114,217,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,213,0, + 0,0,75,4,0,0,115,18,0,0,0,0,2,4,1,4, + 0,2,255,4,2,6,1,4,0,4,255,4,2,122,33,69, + 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, + 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,5,0,0,0,67,0,0,0,115,36,0,0,0,116,0, + 160,1,116,2,106,3,124,1,161,2,1,0,116,0,160,4, + 100,1,124,0,106,5,124,0,106,6,161,3,1,0,100,2, + 83,0,41,3,122,30,73,110,105,116,105,97,108,105,122,101, + 32,97,110,32,101,120,116,101,110,115,105,111,110,32,109,111, + 100,117,108,101,122,40,101,120,116,101,110,115,105,111,110,32, + 109,111,100,117,108,101,32,123,33,114,125,32,101,120,101,99, + 117,116,101,100,32,102,114,111,109,32,123,33,114,125,78,41, + 7,114,135,0,0,0,114,215,0,0,0,114,164,0,0,0, + 90,12,101,120,101,99,95,100,121,110,97,109,105,99,114,150, + 0,0,0,114,117,0,0,0,114,44,0,0,0,114,254,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,218,0,0,0,83,4,0,0,115,10,0,0,0,0, + 2,14,1,6,1,4,0,4,255,122,31,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,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,4,0,0,0,3, + 0,0,0,115,36,0,0,0,116,0,124,0,106,1,131,1, + 100,1,25,0,137,0,116,2,135,0,102,1,100,2,100,3, + 132,8,116,3,68,0,131,1,131,1,83,0,41,4,122,49, + 82,101,116,117,114,110,32,84,114,117,101,32,105,102,32,116, + 104,101,32,101,120,116,101,110,115,105,111,110,32,109,111,100, + 117,108,101,32,105,115,32,97,32,112,97,99,107,97,103,101, + 46,114,39,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,4,0,0,0,51,0,0,0,115, + 26,0,0,0,124,0,93,18,125,1,136,0,100,0,124,1, + 23,0,107,2,86,0,1,0,113,2,100,1,83,0,41,2, + 114,210,0,0,0,78,114,3,0,0,0,169,2,114,32,0, + 0,0,218,6,115,117,102,102,105,120,169,1,90,9,102,105, + 108,101,95,110,97,109,101,114,3,0,0,0,114,6,0,0, + 0,218,9,60,103,101,110,101,120,112,114,62,92,4,0,0, + 115,4,0,0,0,4,1,2,255,122,49,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,105, + 115,95,112,97,99,107,97,103,101,46,60,108,111,99,97,108, + 115,62,46,60,103,101,110,101,120,112,114,62,41,4,114,47, + 0,0,0,114,44,0,0,0,218,3,97,110,121,218,18,69, + 88,84,69,78,83,73,79,78,95,83,85,70,70,73,88,69, + 83,114,220,0,0,0,114,3,0,0,0,114,19,1,0,0, + 114,6,0,0,0,114,183,0,0,0,89,4,0,0,115,8, + 0,0,0,0,2,14,1,12,1,2,255,122,30,69,120,116, + 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, + 46,105,115,95,112,97,99,107,97,103,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, + 63,82,101,116,117,114,110,32,78,111,110,101,32,97,115,32, + 97,110,32,101,120,116,101,110,115,105,111,110,32,109,111,100, + 117,108,101,32,99,97,110,110,111,116,32,99,114,101,97,116, + 101,32,97,32,99,111,100,101,32,111,98,106,101,99,116,46, + 78,114,3,0,0,0,114,220,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,214,0,0,0,95, + 4,0,0,115,2,0,0,0,0,2,122,28,69,120,116,101, 110,115,105,111,110,70,105,108,101,76,111,97,100,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,6,0,0,0,124,0,106,0,83,0,114,250, - 0,0,0,114,48,0,0,0,114,219,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,179,0,0, - 0,98,4,0,0,115,2,0,0,0,0,3,122,32,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,103,101,116,95,102,105,108,101,110,97,109,101,78,41, - 14,114,125,0,0,0,114,124,0,0,0,114,126,0,0,0, - 114,127,0,0,0,114,209,0,0,0,114,243,0,0,0,114, - 247,0,0,0,114,212,0,0,0,114,217,0,0,0,114,182, - 0,0,0,114,213,0,0,0,114,229,0,0,0,114,136,0, - 0,0,114,179,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,252,0,0,0, - 51,4,0,0,115,22,0,0,0,8,2,4,6,8,4,8, - 4,8,3,8,8,8,6,8,6,8,4,8,4,2,1,114, - 252,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,104,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,100,13,132,0,90,9,100,14, - 100,15,132,0,90,10,100,16,100,17,132,0,90,11,100,18, - 100,19,132,0,90,12,100,20,100,21,132,0,90,13,100,22, - 100,23,132,0,90,14,100,24,83,0,41,25,218,14,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,97,38,1,0, - 0,82,101,112,114,101,115,101,110,116,115,32,97,32,110,97, - 109,101,115,112,97,99,101,32,112,97,99,107,97,103,101,39, - 115,32,112,97,116,104,46,32,32,73,116,32,117,115,101,115, - 32,116,104,101,32,109,111,100,117,108,101,32,110,97,109,101, - 10,32,32,32,32,116,111,32,102,105,110,100,32,105,116,115, - 32,112,97,114,101,110,116,32,109,111,100,117,108,101,44,32, - 97,110,100,32,102,114,111,109,32,116,104,101,114,101,32,105, - 116,32,108,111,111,107,115,32,117,112,32,116,104,101,32,112, - 97,114,101,110,116,39,115,10,32,32,32,32,95,95,112,97, - 116,104,95,95,46,32,32,87,104,101,110,32,116,104,105,115, - 32,99,104,97,110,103,101,115,44,32,116,104,101,32,109,111, - 100,117,108,101,39,115,32,111,119,110,32,112,97,116,104,32, - 105,115,32,114,101,99,111,109,112,117,116,101,100,44,10,32, - 32,32,32,117,115,105,110,103,32,112,97,116,104,95,102,105, - 110,100,101,114,46,32,32,70,111,114,32,116,111,112,45,108, - 101,118,101,108,32,109,111,100,117,108,101,115,44,32,116,104, - 101,32,112,97,114,101,110,116,32,109,111,100,117,108,101,39, - 115,32,112,97,116,104,10,32,32,32,32,105,115,32,115,121, - 115,46,112,97,116,104,46,99,4,0,0,0,0,0,0,0, - 0,0,0,0,4,0,0,0,3,0,0,0,67,0,0,0, - 115,36,0,0,0,124,1,124,0,95,0,124,2,124,0,95, - 1,116,2,124,0,160,3,161,0,131,1,124,0,95,4,124, - 3,124,0,95,5,100,0,83,0,114,110,0,0,0,41,6, - 218,5,95,110,97,109,101,218,5,95,112,97,116,104,114,112, - 0,0,0,218,16,95,103,101,116,95,112,97,114,101,110,116, - 95,112,97,116,104,218,17,95,108,97,115,116,95,112,97,114, - 101,110,116,95,112,97,116,104,218,12,95,112,97,116,104,95, - 102,105,110,100,101,114,169,4,114,119,0,0,0,114,117,0, - 0,0,114,44,0,0,0,90,11,112,97,116,104,95,102,105, - 110,100,101,114,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,114,209,0,0,0,111,4,0,0,115,8,0,0, - 0,0,1,6,1,6,1,14,1,122,23,95,78,97,109,101, - 115,112,97,99,101,80,97,116,104,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,38,0,0,0, - 124,0,106,0,160,1,100,1,161,1,92,3,125,1,125,2, - 125,3,124,2,100,2,107,2,114,30,100,3,83,0,124,1, - 100,4,102,2,83,0,41,5,122,62,82,101,116,117,114,110, - 115,32,97,32,116,117,112,108,101,32,111,102,32,40,112,97, - 114,101,110,116,45,109,111,100,117,108,101,45,110,97,109,101, - 44,32,112,97,114,101,110,116,45,112,97,116,104,45,97,116, - 116,114,45,110,97,109,101,41,114,71,0,0,0,114,40,0, - 0,0,41,2,114,8,0,0,0,114,44,0,0,0,90,8, - 95,95,112,97,116,104,95,95,41,2,114,23,1,0,0,114, - 41,0,0,0,41,4,114,119,0,0,0,114,14,1,0,0, - 218,3,100,111,116,90,2,109,101,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,23,95,102,105,110,100,95, - 112,97,114,101,110,116,95,112,97,116,104,95,110,97,109,101, - 115,117,4,0,0,115,8,0,0,0,0,2,18,1,8,2, - 4,3,122,38,95,78,97,109,101,115,112,97,99,101,80,97, - 116,104,46,95,102,105,110,100,95,112,97,114,101,110,116,95, - 112,97,116,104,95,110,97,109,101,115,99,1,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, - 0,0,0,115,28,0,0,0,124,0,160,0,161,0,92,2, - 125,1,125,2,116,1,116,2,106,3,124,1,25,0,124,2, - 131,2,83,0,114,110,0,0,0,41,4,114,30,1,0,0, - 114,130,0,0,0,114,8,0,0,0,218,7,109,111,100,117, - 108,101,115,41,3,114,119,0,0,0,90,18,112,97,114,101, - 110,116,95,109,111,100,117,108,101,95,110,97,109,101,90,14, - 112,97,116,104,95,97,116,116,114,95,110,97,109,101,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,25,1, - 0,0,127,4,0,0,115,4,0,0,0,0,1,12,1,122, - 31,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, - 95,103,101,116,95,112,97,114,101,110,116,95,112,97,116,104, - 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,80,0,0,0,116,0, - 124,0,160,1,161,0,131,1,125,1,124,1,124,0,106,2, - 107,3,114,74,124,0,160,3,124,0,106,4,124,1,161,2, - 125,2,124,2,100,0,107,9,114,68,124,2,106,5,100,0, - 107,8,114,68,124,2,106,6,114,68,124,2,106,6,124,0, - 95,7,124,1,124,0,95,2,124,0,106,7,83,0,114,110, - 0,0,0,41,8,114,112,0,0,0,114,25,1,0,0,114, - 26,1,0,0,114,27,1,0,0,114,23,1,0,0,114,140, - 0,0,0,114,178,0,0,0,114,24,1,0,0,41,3,114, - 119,0,0,0,90,11,112,97,114,101,110,116,95,112,97,116, - 104,114,187,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,12,95,114,101,99,97,108,99,117,108, - 97,116,101,131,4,0,0,115,16,0,0,0,0,2,12,1, - 10,1,14,3,18,1,6,1,8,1,6,1,122,27,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,114,101, - 99,97,108,99,117,108,97,116,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,12,0,0,0,116,0,124,0,160,1,161,0,131, - 1,83,0,114,110,0,0,0,41,2,114,6,1,0,0,114, - 32,1,0,0,114,246,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,8,95,95,105,116,101,114, - 95,95,144,4,0,0,115,2,0,0,0,0,1,122,23,95, - 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, - 105,116,101,114,95,95,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, - 12,0,0,0,124,0,160,0,161,0,124,1,25,0,83,0, - 114,110,0,0,0,169,1,114,32,1,0,0,41,2,114,119, - 0,0,0,218,5,105,110,100,101,120,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,11,95,95,103,101,116, - 105,116,101,109,95,95,147,4,0,0,115,2,0,0,0,0, - 1,122,26,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,46,95,95,103,101,116,105,116,101,109,95,95,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,14,0,0,0,124,2,124,0,106, - 0,124,1,60,0,100,0,83,0,114,110,0,0,0,41,1, - 114,24,1,0,0,41,3,114,119,0,0,0,114,35,1,0, - 0,114,44,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,11,95,95,115,101,116,105,116,101,109, - 95,95,150,4,0,0,115,2,0,0,0,0,1,122,26,95, - 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, - 115,101,116,105,116,101,109,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,12,0,0,0,116,0,124,0,160,1,161,0,131, - 1,83,0,114,110,0,0,0,41,2,114,22,0,0,0,114, - 32,1,0,0,114,246,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,7,95,95,108,101,110,95, - 95,153,4,0,0,115,2,0,0,0,0,1,122,22,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,108, - 101,110,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,12,0, - 0,0,100,1,160,0,124,0,106,1,161,1,83,0,41,2, - 78,122,20,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,40,123,33,114,125,41,41,2,114,62,0,0,0,114,24, - 1,0,0,114,246,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,8,95,95,114,101,112,114,95, - 95,156,4,0,0,115,2,0,0,0,0,1,122,23,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,114, - 101,112,114,95,95,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,12, - 0,0,0,124,1,124,0,160,0,161,0,107,6,83,0,114, - 110,0,0,0,114,34,1,0,0,169,2,114,119,0,0,0, - 218,4,105,116,101,109,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,12,95,95,99,111,110,116,97,105,110, - 115,95,95,159,4,0,0,115,2,0,0,0,0,1,122,27, - 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, - 95,99,111,110,116,97,105,110,115,95,95,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,124,0,106,0,160,1,124, - 1,161,1,1,0,100,0,83,0,114,110,0,0,0,41,2, - 114,24,1,0,0,114,186,0,0,0,114,40,1,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,186, - 0,0,0,162,4,0,0,115,2,0,0,0,0,1,122,21, - 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,97, - 112,112,101,110,100,78,41,15,114,125,0,0,0,114,124,0, - 0,0,114,126,0,0,0,114,127,0,0,0,114,209,0,0, - 0,114,30,1,0,0,114,25,1,0,0,114,32,1,0,0, - 114,33,1,0,0,114,36,1,0,0,114,37,1,0,0,114, - 38,1,0,0,114,39,1,0,0,114,42,1,0,0,114,186, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,22,1,0,0,104,4,0,0, - 115,24,0,0,0,8,1,4,6,8,6,8,10,8,4,8, - 13,8,3,8,3,8,3,8,3,8,3,8,3,114,22,1, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,64,0,0,0,115,80,0,0,0, - 101,0,90,1,100,0,90,2,100,1,100,2,132,0,90,3, - 101,4,100,3,100,4,132,0,131,1,90,5,100,5,100,6, - 132,0,90,6,100,7,100,8,132,0,90,7,100,9,100,10, - 132,0,90,8,100,11,100,12,132,0,90,9,100,13,100,14, - 132,0,90,10,100,15,100,16,132,0,90,11,100,17,83,0, - 41,18,218,16,95,78,97,109,101,115,112,97,99,101,76,111, - 97,100,101,114,99,4,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,4,0,0,0,67,0,0,0,115,18,0, - 0,0,116,0,124,1,124,2,124,3,131,3,124,0,95,1, - 100,0,83,0,114,110,0,0,0,41,2,114,22,1,0,0, - 114,24,1,0,0,114,28,1,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,209,0,0,0,168,4, - 0,0,115,2,0,0,0,0,1,122,25,95,78,97,109,101, - 115,112,97,99,101,76,111,97,100,101,114,46,95,95,105,110, - 105,116,95,95,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,12,0, - 0,0,100,1,160,0,124,1,106,1,161,1,83,0,41,2, - 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,122,25,60,109,111,100,117,108,101,32,123, - 33,114,125,32,40,110,97,109,101,115,112,97,99,101,41,62, - 41,2,114,62,0,0,0,114,125,0,0,0,41,2,114,193, - 0,0,0,114,216,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,11,109,111,100,117,108,101,95, - 114,101,112,114,171,4,0,0,115,2,0,0,0,0,7,122, - 28,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, - 114,46,109,111,100,117,108,101,95,114,101,112,114,99,2,0, + 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,53,82,101, + 116,117,114,110,32,78,111,110,101,32,97,115,32,101,120,116, + 101,110,115,105,111,110,32,109,111,100,117,108,101,115,32,104, + 97,118,101,32,110,111,32,115,111,117,114,99,101,32,99,111, + 100,101,46,78,114,3,0,0,0,114,220,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,230,0, + 0,0,99,4,0,0,115,2,0,0,0,0,2,122,30,69, + 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, + 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,78,84,114,3,0,0,0,114,219,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,182,0,0, - 0,180,4,0,0,115,2,0,0,0,0,1,122,27,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,105, - 115,95,112,97,99,107,97,103,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,78,114,40, - 0,0,0,114,3,0,0,0,114,219,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,229,0,0, - 0,183,4,0,0,115,2,0,0,0,0,1,122,27,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,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,6,0,0,0,67,0, - 0,0,115,16,0,0,0,116,0,100,1,100,2,100,3,100, - 4,100,5,141,4,83,0,41,6,78,114,40,0,0,0,122, - 8,60,115,116,114,105,110,103,62,114,215,0,0,0,84,41, - 1,114,231,0,0,0,41,1,114,232,0,0,0,114,219,0, + 0,0,67,0,0,0,115,6,0,0,0,124,0,106,0,83, + 0,114,251,0,0,0,114,48,0,0,0,114,220,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 180,0,0,0,103,4,0,0,115,2,0,0,0,0,3,122, + 32,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, + 97,100,101,114,46,103,101,116,95,102,105,108,101,110,97,109, + 101,78,41,14,114,126,0,0,0,114,125,0,0,0,114,127, + 0,0,0,114,128,0,0,0,114,210,0,0,0,114,244,0, + 0,0,114,248,0,0,0,114,213,0,0,0,114,218,0,0, + 0,114,183,0,0,0,114,214,0,0,0,114,230,0,0,0, + 114,137,0,0,0,114,180,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,253, + 0,0,0,56,4,0,0,115,22,0,0,0,8,2,4,6, + 8,4,8,4,8,3,8,8,8,6,8,6,8,4,8,4, + 2,1,114,253,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,104,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,100,13,132,0,90, + 9,100,14,100,15,132,0,90,10,100,16,100,17,132,0,90, + 11,100,18,100,19,132,0,90,12,100,20,100,21,132,0,90, + 13,100,22,100,23,132,0,90,14,100,24,83,0,41,25,218, + 14,95,78,97,109,101,115,112,97,99,101,80,97,116,104,97, + 38,1,0,0,82,101,112,114,101,115,101,110,116,115,32,97, + 32,110,97,109,101,115,112,97,99,101,32,112,97,99,107,97, + 103,101,39,115,32,112,97,116,104,46,32,32,73,116,32,117, + 115,101,115,32,116,104,101,32,109,111,100,117,108,101,32,110, + 97,109,101,10,32,32,32,32,116,111,32,102,105,110,100,32, + 105,116,115,32,112,97,114,101,110,116,32,109,111,100,117,108, + 101,44,32,97,110,100,32,102,114,111,109,32,116,104,101,114, + 101,32,105,116,32,108,111,111,107,115,32,117,112,32,116,104, + 101,32,112,97,114,101,110,116,39,115,10,32,32,32,32,95, + 95,112,97,116,104,95,95,46,32,32,87,104,101,110,32,116, + 104,105,115,32,99,104,97,110,103,101,115,44,32,116,104,101, + 32,109,111,100,117,108,101,39,115,32,111,119,110,32,112,97, + 116,104,32,105,115,32,114,101,99,111,109,112,117,116,101,100, + 44,10,32,32,32,32,117,115,105,110,103,32,112,97,116,104, + 95,102,105,110,100,101,114,46,32,32,70,111,114,32,116,111, + 112,45,108,101,118,101,108,32,109,111,100,117,108,101,115,44, + 32,116,104,101,32,112,97,114,101,110,116,32,109,111,100,117, + 108,101,39,115,32,112,97,116,104,10,32,32,32,32,105,115, + 32,115,121,115,46,112,97,116,104,46,99,4,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,67, + 0,0,0,115,36,0,0,0,124,1,124,0,95,0,124,2, + 124,0,95,1,116,2,124,0,160,3,161,0,131,1,124,0, + 95,4,124,3,124,0,95,5,100,0,83,0,114,110,0,0, + 0,41,6,218,5,95,110,97,109,101,218,5,95,112,97,116, + 104,114,112,0,0,0,218,16,95,103,101,116,95,112,97,114, + 101,110,116,95,112,97,116,104,218,17,95,108,97,115,116,95, + 112,97,114,101,110,116,95,112,97,116,104,218,12,95,112,97, + 116,104,95,102,105,110,100,101,114,169,4,114,119,0,0,0, + 114,117,0,0,0,114,44,0,0,0,90,11,112,97,116,104, + 95,102,105,110,100,101,114,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,210,0,0,0,116,4,0,0,115, + 8,0,0,0,0,1,6,1,6,1,14,1,122,23,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,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,38, + 0,0,0,124,0,106,0,160,1,100,1,161,1,92,3,125, + 1,125,2,125,3,124,2,100,2,107,2,114,30,100,3,83, + 0,124,1,100,4,102,2,83,0,41,5,122,62,82,101,116, + 117,114,110,115,32,97,32,116,117,112,108,101,32,111,102,32, + 40,112,97,114,101,110,116,45,109,111,100,117,108,101,45,110, + 97,109,101,44,32,112,97,114,101,110,116,45,112,97,116,104, + 45,97,116,116,114,45,110,97,109,101,41,114,71,0,0,0, + 114,40,0,0,0,41,2,114,8,0,0,0,114,44,0,0, + 0,90,8,95,95,112,97,116,104,95,95,41,2,114,24,1, + 0,0,114,41,0,0,0,41,4,114,119,0,0,0,114,15, + 1,0,0,218,3,100,111,116,90,2,109,101,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,23,95,102,105, + 110,100,95,112,97,114,101,110,116,95,112,97,116,104,95,110, + 97,109,101,115,122,4,0,0,115,8,0,0,0,0,2,18, + 1,8,2,4,3,122,38,95,78,97,109,101,115,112,97,99, + 101,80,97,116,104,46,95,102,105,110,100,95,112,97,114,101, + 110,116,95,112,97,116,104,95,110,97,109,101,115,99,1,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0, + 0,0,67,0,0,0,115,28,0,0,0,124,0,160,0,161, + 0,92,2,125,1,125,2,116,1,116,2,106,3,124,1,25, + 0,124,2,131,2,83,0,114,110,0,0,0,41,4,114,31, + 1,0,0,114,131,0,0,0,114,8,0,0,0,218,7,109, + 111,100,117,108,101,115,41,3,114,119,0,0,0,90,18,112, + 97,114,101,110,116,95,109,111,100,117,108,101,95,110,97,109, + 101,90,14,112,97,116,104,95,97,116,116,114,95,110,97,109, + 101,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,26,1,0,0,132,4,0,0,115,4,0,0,0,0,1, + 12,1,122,31,95,78,97,109,101,115,112,97,99,101,80,97, + 116,104,46,95,103,101,116,95,112,97,114,101,110,116,95,112, + 97,116,104,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,80,0,0, + 0,116,0,124,0,160,1,161,0,131,1,125,1,124,1,124, + 0,106,2,107,3,114,74,124,0,160,3,124,0,106,4,124, + 1,161,2,125,2,124,2,100,0,107,9,114,68,124,2,106, + 5,100,0,107,8,114,68,124,2,106,6,114,68,124,2,106, + 6,124,0,95,7,124,1,124,0,95,2,124,0,106,7,83, + 0,114,110,0,0,0,41,8,114,112,0,0,0,114,26,1, + 0,0,114,27,1,0,0,114,28,1,0,0,114,24,1,0, + 0,114,141,0,0,0,114,179,0,0,0,114,25,1,0,0, + 41,3,114,119,0,0,0,90,11,112,97,114,101,110,116,95, + 112,97,116,104,114,188,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,12,95,114,101,99,97,108, + 99,117,108,97,116,101,136,4,0,0,115,16,0,0,0,0, + 2,12,1,10,1,14,3,18,1,6,1,8,1,6,1,122, + 27,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 95,114,101,99,97,108,99,117,108,97,116,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,12,0,0,0,116,0,124,0,160,1, + 161,0,131,1,83,0,114,110,0,0,0,41,2,114,7,1, + 0,0,114,33,1,0,0,114,247,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,8,95,95,105, + 116,101,114,95,95,149,4,0,0,115,2,0,0,0,0,1, + 122,23,95,78,97,109,101,115,112,97,99,101,80,97,116,104, + 46,95,95,105,116,101,114,95,95,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,12,0,0,0,124,0,160,0,161,0,124,1,25, + 0,83,0,114,110,0,0,0,169,1,114,33,1,0,0,41, + 2,114,119,0,0,0,218,5,105,110,100,101,120,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,11,95,95, + 103,101,116,105,116,101,109,95,95,152,4,0,0,115,2,0, + 0,0,0,1,122,26,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,46,95,95,103,101,116,105,116,101,109,95,95, + 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,14,0,0,0,124,2, + 124,0,106,0,124,1,60,0,100,0,83,0,114,110,0,0, + 0,41,1,114,25,1,0,0,41,3,114,119,0,0,0,114, + 36,1,0,0,114,44,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,11,95,95,115,101,116,105, + 116,101,109,95,95,155,4,0,0,115,2,0,0,0,0,1, + 122,26,95,78,97,109,101,115,112,97,99,101,80,97,116,104, + 46,95,95,115,101,116,105,116,101,109,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,12,0,0,0,116,0,124,0,160,1, + 161,0,131,1,83,0,114,110,0,0,0,41,2,114,22,0, + 0,0,114,33,1,0,0,114,247,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,7,95,95,108, + 101,110,95,95,158,4,0,0,115,2,0,0,0,0,1,122, + 22,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 95,95,108,101,110,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,12,0,0,0,100,1,160,0,124,0,106,1,161,1,83, + 0,41,2,78,122,20,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,40,123,33,114,125,41,41,2,114,62,0,0, + 0,114,25,1,0,0,114,247,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,8,95,95,114,101, + 112,114,95,95,161,4,0,0,115,2,0,0,0,0,1,122, + 23,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 95,95,114,101,112,114,95,95,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,12,0,0,0,124,1,124,0,160,0,161,0,107,6, + 83,0,114,110,0,0,0,114,35,1,0,0,169,2,114,119, + 0,0,0,218,4,105,116,101,109,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,12,95,95,99,111,110,116, + 97,105,110,115,95,95,164,4,0,0,115,2,0,0,0,0, + 1,122,27,95,78,97,109,101,115,112,97,99,101,80,97,116, + 104,46,95,95,99,111,110,116,97,105,110,115,95,95,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,124,0,106,0, + 160,1,124,1,161,1,1,0,100,0,83,0,114,110,0,0, + 0,41,2,114,25,1,0,0,114,187,0,0,0,114,41,1, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,213,0,0,0,186,4,0,0,115,2,0,0,0,0, - 1,122,25,95,78,97,109,101,115,112,97,99,101,76,111,97, - 100,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,114,210, - 0,0,0,114,3,0,0,0,114,211,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,212,0,0, - 0,189,4,0,0,115,2,0,0,0,0,1,122,30,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,99, - 114,101,97,116,101,95,109,111,100,117,108,101,99,2,0,0, + 0,114,187,0,0,0,167,4,0,0,115,2,0,0,0,0, + 1,122,21,95,78,97,109,101,115,112,97,99,101,80,97,116, + 104,46,97,112,112,101,110,100,78,41,15,114,126,0,0,0, + 114,125,0,0,0,114,127,0,0,0,114,128,0,0,0,114, + 210,0,0,0,114,31,1,0,0,114,26,1,0,0,114,33, + 1,0,0,114,34,1,0,0,114,37,1,0,0,114,38,1, + 0,0,114,39,1,0,0,114,40,1,0,0,114,43,1,0, + 0,114,187,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,23,1,0,0,109, + 4,0,0,115,24,0,0,0,8,1,4,6,8,6,8,10, + 8,4,8,13,8,3,8,3,8,3,8,3,8,3,8,3, + 114,23,1,0,0,99,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,64,0,0,0,115,80, + 0,0,0,101,0,90,1,100,0,90,2,100,1,100,2,132, + 0,90,3,101,4,100,3,100,4,132,0,131,1,90,5,100, + 5,100,6,132,0,90,6,100,7,100,8,132,0,90,7,100, + 9,100,10,132,0,90,8,100,11,100,12,132,0,90,9,100, + 13,100,14,132,0,90,10,100,15,100,16,132,0,90,11,100, + 17,83,0,41,18,218,16,95,78,97,109,101,115,112,97,99, + 101,76,111,97,100,101,114,99,4,0,0,0,0,0,0,0, + 0,0,0,0,4,0,0,0,4,0,0,0,67,0,0,0, + 115,18,0,0,0,116,0,124,1,124,2,124,3,131,3,124, + 0,95,1,100,0,83,0,114,110,0,0,0,41,2,114,23, + 1,0,0,114,25,1,0,0,114,29,1,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,210,0,0, + 0,173,4,0,0,115,2,0,0,0,0,1,122,25,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,95, + 95,105,110,105,116,95,95,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,12,0,0,0,100,1,160,0,124,1,106,1,161,1,83, + 0,41,2,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,122,25,60,109,111,100,117,108, + 101,32,123,33,114,125,32,40,110,97,109,101,115,112,97,99, + 101,41,62,41,2,114,62,0,0,0,114,126,0,0,0,41, + 2,114,194,0,0,0,114,217,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,11,109,111,100,117, + 108,101,95,114,101,112,114,176,4,0,0,115,2,0,0,0, + 0,7,122,28,95,78,97,109,101,115,112,97,99,101,76,111, + 97,100,101,114,46,109,111,100,117,108,101,95,114,101,112,114, + 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,78,84,114,3,0,0,0,114,220,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 183,0,0,0,185,4,0,0,115,2,0,0,0,0,1,122, + 27,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, + 114,46,105,115,95,112,97,99,107,97,103,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,0,83,0,114,110, - 0,0,0,114,3,0,0,0,114,253,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,217,0,0, - 0,192,4,0,0,115,2,0,0,0,0,1,122,28,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,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,4,0,0,0,67, - 0,0,0,115,26,0,0,0,116,0,160,1,100,1,124,0, - 106,2,161,2,1,0,116,0,160,3,124,0,124,1,161,2, - 83,0,41,2,122,98,76,111,97,100,32,97,32,110,97,109, - 101,115,112,97,99,101,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,122,38,110,97,109,101,115,112, - 97,99,101,32,109,111,100,117,108,101,32,108,111,97,100,101, - 100,32,119,105,116,104,32,112,97,116,104,32,123,33,114,125, - 41,4,114,134,0,0,0,114,149,0,0,0,114,24,1,0, - 0,114,218,0,0,0,114,219,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,220,0,0,0,195, - 4,0,0,115,8,0,0,0,0,7,6,1,4,255,4,2, - 122,28,95,78,97,109,101,115,112,97,99,101,76,111,97,100, - 101,114,46,108,111,97,100,95,109,111,100,117,108,101,78,41, - 12,114,125,0,0,0,114,124,0,0,0,114,126,0,0,0, - 114,209,0,0,0,114,207,0,0,0,114,44,1,0,0,114, - 182,0,0,0,114,229,0,0,0,114,213,0,0,0,114,212, - 0,0,0,114,217,0,0,0,114,220,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,43,1,0,0,167,4,0,0,115,18,0,0,0,8, - 1,8,3,2,1,10,8,8,3,8,3,8,3,8,3,8, - 3,114,43,1,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, - 172,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, - 101,4,100,2,100,3,132,0,131,1,90,5,101,4,100,4, - 100,5,132,0,131,1,90,6,101,4,100,6,100,7,132,0, - 131,1,90,7,101,4,100,8,100,9,132,0,131,1,90,8, - 101,4,100,28,100,11,100,12,132,1,131,1,90,9,101,4, - 100,29,100,13,100,14,132,1,131,1,90,10,101,4,100,30, - 100,15,100,16,132,1,131,1,90,11,100,17,90,12,101,4, - 100,31,100,18,100,19,132,1,131,1,90,13,101,4,100,20, - 100,21,132,0,131,1,90,14,101,15,100,22,100,23,132,0, - 131,1,90,16,101,4,100,24,100,25,132,0,131,1,90,17, - 101,4,100,26,100,27,132,0,131,1,90,18,100,10,83,0, - 41,32,218,10,80,97,116,104,70,105,110,100,101,114,122,62, - 77,101,116,97,32,112,97,116,104,32,102,105,110,100,101,114, - 32,102,111,114,32,115,121,115,46,112,97,116,104,32,97,110, - 100,32,112,97,99,107,97,103,101,32,95,95,112,97,116,104, - 95,95,32,97,116,116,114,105,98,117,116,101,115,46,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,116,0,116,1, - 106,2,160,3,161,0,131,1,68,0,93,44,92,2,125,1, - 125,2,124,2,100,1,107,8,114,40,116,1,106,2,124,1, - 61,0,113,14,116,4,124,2,100,2,131,2,114,14,124,2, - 160,5,161,0,1,0,113,14,100,1,83,0,41,3,122,125, - 67,97,108,108,32,116,104,101,32,105,110,118,97,108,105,100, - 97,116,101,95,99,97,99,104,101,115,40,41,32,109,101,116, - 104,111,100,32,111,110,32,97,108,108,32,112,97,116,104,32, - 101,110,116,114,121,32,102,105,110,100,101,114,115,10,32,32, - 32,32,32,32,32,32,115,116,111,114,101,100,32,105,110,32, - 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, - 114,95,99,97,99,104,101,115,32,40,119,104,101,114,101,32, - 105,109,112,108,101,109,101,110,116,101,100,41,46,78,218,17, - 105,110,118,97,108,105,100,97,116,101,95,99,97,99,104,101, - 115,41,6,218,4,108,105,115,116,114,8,0,0,0,218,19, - 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,218,5,105,116,101,109,115,114,128,0,0,0,114, - 46,1,0,0,41,3,114,193,0,0,0,114,117,0,0,0, - 218,6,102,105,110,100,101,114,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,46,1,0,0,213,4,0,0, - 115,10,0,0,0,0,4,22,1,8,1,10,1,10,1,122, - 28,80,97,116,104,70,105,110,100,101,114,46,105,110,118,97, - 108,105,100,97,116,101,95,99,97,99,104,101,115,99,2,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,9,0, - 0,0,67,0,0,0,115,84,0,0,0,116,0,106,1,100, - 1,107,9,114,28,116,0,106,1,115,28,116,2,160,3,100, - 2,116,4,161,2,1,0,116,0,106,1,68,0,93,44,125, - 2,122,14,124,2,124,1,131,1,87,0,2,0,1,0,83, - 0,4,0,116,5,107,10,114,76,1,0,1,0,1,0,89, - 0,113,34,89,0,113,34,88,0,113,34,100,1,83,0,41, - 3,122,46,83,101,97,114,99,104,32,115,121,115,46,112,97, - 116,104,95,104,111,111,107,115,32,102,111,114,32,97,32,102, - 105,110,100,101,114,32,102,111,114,32,39,112,97,116,104,39, - 46,78,122,23,115,121,115,46,112,97,116,104,95,104,111,111, - 107,115,32,105,115,32,101,109,112,116,121,41,6,114,8,0, - 0,0,218,10,112,97,116,104,95,104,111,111,107,115,114,75, - 0,0,0,114,76,0,0,0,114,138,0,0,0,114,118,0, - 0,0,41,3,114,193,0,0,0,114,44,0,0,0,90,4, - 104,111,111,107,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,11,95,112,97,116,104,95,104,111,111,107,115, - 223,4,0,0,115,16,0,0,0,0,3,16,1,12,1,10, - 1,2,1,14,1,14,1,12,2,122,22,80,97,116,104,70, - 105,110,100,101,114,46,95,112,97,116,104,95,104,111,111,107, - 115,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,104,0,0,0,124, - 1,100,1,107,2,114,44,122,12,116,0,160,1,161,0,125, - 1,87,0,110,22,4,0,116,2,107,10,114,42,1,0,1, - 0,1,0,89,0,100,2,83,0,88,0,122,14,116,3,106, - 4,124,1,25,0,125,2,87,0,110,40,4,0,116,5,107, - 10,114,98,1,0,1,0,1,0,124,0,160,6,124,1,161, - 1,125,2,124,2,116,3,106,4,124,1,60,0,89,0,110, - 2,88,0,124,2,83,0,41,3,122,210,71,101,116,32,116, - 104,101,32,102,105,110,100,101,114,32,102,111,114,32,116,104, - 101,32,112,97,116,104,32,101,110,116,114,121,32,102,114,111, - 109,32,115,121,115,46,112,97,116,104,95,105,109,112,111,114, - 116,101,114,95,99,97,99,104,101,46,10,10,32,32,32,32, - 32,32,32,32,73,102,32,116,104,101,32,112,97,116,104,32, - 101,110,116,114,121,32,105,115,32,110,111,116,32,105,110,32, - 116,104,101,32,99,97,99,104,101,44,32,102,105,110,100,32, - 116,104,101,32,97,112,112,114,111,112,114,105,97,116,101,32, - 102,105,110,100,101,114,10,32,32,32,32,32,32,32,32,97, - 110,100,32,99,97,99,104,101,32,105,116,46,32,73,102,32, - 110,111,32,102,105,110,100,101,114,32,105,115,32,97,118,97, - 105,108,97,98,108,101,44,32,115,116,111,114,101,32,78,111, - 110,101,46,10,10,32,32,32,32,32,32,32,32,114,40,0, - 0,0,78,41,7,114,2,0,0,0,114,55,0,0,0,114, - 3,1,0,0,114,8,0,0,0,114,48,1,0,0,218,8, - 75,101,121,69,114,114,111,114,114,52,1,0,0,41,3,114, - 193,0,0,0,114,44,0,0,0,114,50,1,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,20,95, - 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,236,4,0,0,115,22,0,0,0,0,8,8,1, - 2,1,12,1,14,3,8,1,2,1,14,1,14,1,10,1, - 16,1,122,31,80,97,116,104,70,105,110,100,101,114,46,95, - 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,99,3,0,0,0,0,0,0,0,0,0,0,0, - 6,0,0,0,4,0,0,0,67,0,0,0,115,82,0,0, - 0,116,0,124,2,100,1,131,2,114,26,124,2,160,1,124, - 1,161,1,92,2,125,3,125,4,110,14,124,2,160,2,124, - 1,161,1,125,3,103,0,125,4,124,3,100,0,107,9,114, - 60,116,3,160,4,124,1,124,3,161,2,83,0,116,3,160, - 5,124,1,100,0,161,2,125,5,124,4,124,5,95,6,124, - 5,83,0,41,2,78,114,137,0,0,0,41,7,114,128,0, - 0,0,114,137,0,0,0,114,206,0,0,0,114,134,0,0, - 0,114,201,0,0,0,114,183,0,0,0,114,178,0,0,0, - 41,6,114,193,0,0,0,114,139,0,0,0,114,50,1,0, - 0,114,140,0,0,0,114,141,0,0,0,114,187,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 16,95,108,101,103,97,99,121,95,103,101,116,95,115,112,101, - 99,2,5,0,0,115,18,0,0,0,0,4,10,1,16,2, - 10,1,4,1,8,1,12,1,12,1,6,1,122,27,80,97, - 116,104,70,105,110,100,101,114,46,95,108,101,103,97,99,121, - 95,103,101,116,95,115,112,101,99,78,99,4,0,0,0,0, - 0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,67, - 0,0,0,115,166,0,0,0,103,0,125,4,124,2,68,0, - 93,134,125,5,116,0,124,5,116,1,116,2,102,2,131,2, - 115,28,113,8,124,0,160,3,124,5,161,1,125,6,124,6, - 100,1,107,9,114,8,116,4,124,6,100,2,131,2,114,70, - 124,6,160,5,124,1,124,3,161,2,125,7,110,12,124,0, - 160,6,124,1,124,6,161,2,125,7,124,7,100,1,107,8, - 114,92,113,8,124,7,106,7,100,1,107,9,114,110,124,7, - 2,0,1,0,83,0,124,7,106,8,125,8,124,8,100,1, - 107,8,114,132,116,9,100,3,131,1,130,1,124,4,160,10, - 124,8,161,1,1,0,113,8,116,11,160,12,124,1,100,1, - 161,2,125,7,124,4,124,7,95,8,124,7,83,0,41,4, - 122,63,70,105,110,100,32,116,104,101,32,108,111,97,100,101, - 114,32,111,114,32,110,97,109,101,115,112,97,99,101,95,112, - 97,116,104,32,102,111,114,32,116,104,105,115,32,109,111,100, - 117,108,101,47,112,97,99,107,97,103,101,32,110,97,109,101, - 46,78,114,203,0,0,0,122,19,115,112,101,99,32,109,105, - 115,115,105,110,103,32,108,111,97,100,101,114,41,13,114,161, - 0,0,0,114,85,0,0,0,218,5,98,121,116,101,115,114, - 54,1,0,0,114,128,0,0,0,114,203,0,0,0,114,55, - 1,0,0,114,140,0,0,0,114,178,0,0,0,114,118,0, - 0,0,114,167,0,0,0,114,134,0,0,0,114,183,0,0, - 0,41,9,114,193,0,0,0,114,139,0,0,0,114,44,0, - 0,0,114,202,0,0,0,218,14,110,97,109,101,115,112,97, - 99,101,95,112,97,116,104,90,5,101,110,116,114,121,114,50, - 1,0,0,114,187,0,0,0,114,141,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,9,95,103, - 101,116,95,115,112,101,99,17,5,0,0,115,40,0,0,0, - 0,5,4,1,8,1,14,1,2,1,10,1,8,1,10,1, - 14,2,12,1,8,1,2,1,10,1,8,1,6,1,8,1, - 8,5,12,2,12,1,6,1,122,20,80,97,116,104,70,105, - 110,100,101,114,46,95,103,101,116,95,115,112,101,99,99,4, - 0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,5, - 0,0,0,67,0,0,0,115,100,0,0,0,124,2,100,1, - 107,8,114,14,116,0,106,1,125,2,124,0,160,2,124,1, - 124,2,124,3,161,3,125,4,124,4,100,1,107,8,114,40, - 100,1,83,0,124,4,106,3,100,1,107,8,114,92,124,4, - 106,4,125,5,124,5,114,86,100,1,124,4,95,5,116,6, - 124,1,124,5,124,0,106,2,131,3,124,4,95,4,124,4, - 83,0,100,1,83,0,110,4,124,4,83,0,100,1,83,0, - 41,2,122,141,84,114,121,32,116,111,32,102,105,110,100,32, - 97,32,115,112,101,99,32,102,111,114,32,39,102,117,108,108, - 110,97,109,101,39,32,111,110,32,115,121,115,46,112,97,116, - 104,32,111,114,32,39,112,97,116,104,39,46,10,10,32,32, - 32,32,32,32,32,32,84,104,101,32,115,101,97,114,99,104, - 32,105,115,32,98,97,115,101,100,32,111,110,32,115,121,115, - 46,112,97,116,104,95,104,111,111,107,115,32,97,110,100,32, - 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, - 114,95,99,97,99,104,101,46,10,32,32,32,32,32,32,32, - 32,78,41,7,114,8,0,0,0,114,44,0,0,0,114,58, - 1,0,0,114,140,0,0,0,114,178,0,0,0,114,181,0, - 0,0,114,22,1,0,0,41,6,114,193,0,0,0,114,139, - 0,0,0,114,44,0,0,0,114,202,0,0,0,114,187,0, - 0,0,114,57,1,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,203,0,0,0,49,5,0,0,115, - 26,0,0,0,0,6,8,1,6,1,14,1,8,1,4,1, - 10,1,6,1,4,3,6,1,16,1,4,2,6,2,122,20, - 80,97,116,104,70,105,110,100,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,8,114,24,100,1,83,0,124,3,106,1,83,0, - 41,2,122,170,102,105,110,100,32,116,104,101,32,109,111,100, - 117,108,101,32,111,110,32,115,121,115,46,112,97,116,104,32, - 111,114,32,39,112,97,116,104,39,32,98,97,115,101,100,32, - 111,110,32,115,121,115,46,112,97,116,104,95,104,111,111,107, - 115,32,97,110,100,10,32,32,32,32,32,32,32,32,115,121, - 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, - 99,97,99,104,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,114, - 204,0,0,0,114,205,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,206,0,0,0,73,5,0, - 0,115,8,0,0,0,0,8,12,1,8,1,4,1,122,22, - 80,97,116,104,70,105,110,100,101,114,46,102,105,110,100,95, - 109,111,100,117,108,101,122,45,40,63,58,123,112,97,116,116, - 101,114,110,125,40,45,46,42,41,63,92,46,40,100,105,115, - 116,124,101,103,103,41,45,105,110,102,111,124,69,71,71,45, - 73,78,70,79,41,99,3,0,0,0,0,0,0,0,0,0, - 0,0,7,0,0,0,4,0,0,0,67,0,0,0,115,78, - 0,0,0,100,1,100,2,108,0,125,3,100,1,100,3,108, - 1,109,2,125,4,1,0,124,2,100,2,107,8,114,34,116, - 3,106,4,125,2,124,1,100,2,107,8,114,46,100,4,110, - 8,124,3,160,5,124,1,161,1,125,5,124,0,160,6,124, - 5,124,2,161,2,125,6,116,7,124,4,124,6,131,2,83, - 0,41,5,97,37,1,0,0,10,32,32,32,32,32,32,32, - 32,70,105,110,100,32,100,105,115,116,114,105,98,117,116,105, - 111,110,115,46,10,10,32,32,32,32,32,32,32,32,82,101, - 116,117,114,110,32,97,110,32,105,116,101,114,97,98,108,101, - 32,111,102,32,97,108,108,32,68,105,115,116,114,105,98,117, - 116,105,111,110,32,105,110,115,116,97,110,99,101,115,32,99, - 97,112,97,98,108,101,32,111,102,10,32,32,32,32,32,32, - 32,32,108,111,97,100,105,110,103,32,116,104,101,32,109,101, - 116,97,100,97,116,97,32,102,111,114,32,112,97,99,107,97, - 103,101,115,32,109,97,116,99,104,105,110,103,32,116,104,101, - 32,96,96,110,97,109,101,96,96,10,32,32,32,32,32,32, - 32,32,40,111,114,32,97,108,108,32,110,97,109,101,115,32, - 105,102,32,110,111,116,32,115,117,112,112,108,105,101,100,41, - 32,97,108,111,110,103,32,116,104,101,32,112,97,116,104,115, - 32,105,110,32,116,104,101,32,108,105,115,116,10,32,32,32, - 32,32,32,32,32,111,102,32,100,105,114,101,99,116,111,114, - 105,101,115,32,96,96,112,97,116,104,96,96,32,40,100,101, - 102,97,117,108,116,115,32,116,111,32,115,121,115,46,112,97, - 116,104,41,46,10,32,32,32,32,32,32,32,32,114,73,0, - 0,0,78,41,1,218,16,80,97,116,104,68,105,115,116,114, - 105,98,117,116,105,111,110,122,2,46,42,41,8,218,2,114, - 101,90,18,105,109,112,111,114,116,108,105,98,46,109,101,116, - 97,100,97,116,97,114,59,1,0,0,114,8,0,0,0,114, - 44,0,0,0,90,6,101,115,99,97,112,101,218,13,95,115, - 101,97,114,99,104,95,112,97,116,104,115,218,3,109,97,112, - 41,7,114,193,0,0,0,114,117,0,0,0,114,44,0,0, - 0,114,60,1,0,0,114,59,1,0,0,218,7,112,97,116, - 116,101,114,110,90,5,102,111,117,110,100,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,18,102,105,110,100, - 95,100,105,115,116,114,105,98,117,116,105,111,110,115,88,5, - 0,0,115,14,0,0,0,0,10,8,1,12,1,8,1,6, - 1,22,1,12,1,122,29,80,97,116,104,70,105,110,100,101, - 114,46,102,105,110,100,95,100,105,115,116,114,105,98,117,116, - 105,111,110,115,99,3,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,6,0,0,0,3,0,0,0,115,44,0, - 0,0,100,1,100,2,108,0,125,3,124,3,106,1,160,2, - 135,0,135,1,102,2,100,3,100,4,132,8,116,3,136,0, - 106,4,124,2,131,2,68,0,131,1,161,1,83,0,41,5, - 122,49,70,105,110,100,32,109,101,116,97,100,97,116,97,32, - 100,105,114,101,99,116,111,114,105,101,115,32,105,110,32,112, - 97,116,104,115,32,104,101,117,114,105,115,116,105,99,97,108, - 108,121,46,114,73,0,0,0,78,99,1,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,5,0,0,0,51,0, - 0,0,115,26,0,0,0,124,0,93,18,125,1,136,0,160, - 0,124,1,136,1,161,2,86,0,1,0,113,2,100,0,83, - 0,114,110,0,0,0,41,1,218,12,95,115,101,97,114,99, - 104,95,112,97,116,104,41,2,114,32,0,0,0,114,44,0, - 0,0,169,2,114,193,0,0,0,114,63,1,0,0,114,3, - 0,0,0,114,6,0,0,0,114,19,1,0,0,110,5,0, - 0,115,4,0,0,0,4,2,2,255,122,43,80,97,116,104, - 70,105,110,100,101,114,46,95,115,101,97,114,99,104,95,112, - 97,116,104,115,46,60,108,111,99,97,108,115,62,46,60,103, - 101,110,101,120,112,114,62,41,5,218,9,105,116,101,114,116, - 111,111,108,115,90,5,99,104,97,105,110,90,13,102,114,111, - 109,95,105,116,101,114,97,98,108,101,114,62,1,0,0,218, - 12,95,115,119,105,116,99,104,95,112,97,116,104,41,4,114, - 193,0,0,0,114,63,1,0,0,90,5,112,97,116,104,115, - 114,67,1,0,0,114,3,0,0,0,114,66,1,0,0,114, - 6,0,0,0,114,61,1,0,0,106,5,0,0,115,8,0, - 0,0,0,3,8,1,18,2,10,254,122,24,80,97,116,104, - 70,105,110,100,101,114,46,95,115,101,97,114,99,104,95,112, - 97,116,104,115,99,1,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,10,0,0,0,67,0,0,0,115,78,0, - 0,0,100,1,100,2,108,0,109,1,125,1,1,0,100,1, - 100,0,108,2,125,2,100,1,100,3,108,3,109,4,125,3, - 1,0,124,1,116,5,131,1,143,24,1,0,124,2,160,4, - 124,0,161,1,87,0,2,0,53,0,81,0,82,0,163,0, - 83,0,81,0,82,0,88,0,124,3,124,0,131,1,83,0, - 41,4,78,114,73,0,0,0,41,1,218,8,115,117,112,112, - 114,101,115,115,41,1,218,4,80,97,116,104,41,6,90,10, - 99,111,110,116,101,120,116,108,105,98,114,69,1,0,0,218, - 7,122,105,112,102,105,108,101,90,7,112,97,116,104,108,105, - 98,114,70,1,0,0,218,9,69,120,99,101,112,116,105,111, - 110,41,4,114,44,0,0,0,114,69,1,0,0,114,71,1, - 0,0,114,70,1,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,68,1,0,0,115,5,0,0,115, - 12,0,0,0,0,2,12,1,8,1,12,1,10,1,28,1, - 122,23,80,97,116,104,70,105,110,100,101,114,46,95,115,119, - 105,116,99,104,95,112,97,116,104,99,4,0,0,0,0,0, - 0,0,0,0,0,0,5,0,0,0,5,0,0,0,67,0, - 0,0,115,32,0,0,0,100,1,100,0,108,0,125,4,124, - 4,106,1,124,1,116,2,124,3,106,3,131,1,124,4,106, - 4,100,2,141,3,83,0,41,3,78,114,73,0,0,0,41, - 1,114,83,0,0,0,41,5,114,60,1,0,0,90,5,109, - 97,116,99,104,114,85,0,0,0,114,117,0,0,0,90,10, - 73,71,78,79,82,69,67,65,83,69,41,5,114,193,0,0, - 0,114,63,1,0,0,218,4,114,111,111,116,114,41,1,0, - 0,114,60,1,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,10,95,112,114,101,100,105,99,97,116, - 101,124,5,0,0,115,4,0,0,0,0,2,8,1,122,21, - 80,97,116,104,70,105,110,100,101,114,46,95,112,114,101,100, - 105,99,97,116,101,99,3,0,0,0,0,0,0,0,0,0, - 0,0,4,0,0,0,4,0,0,0,3,0,0,0,115,64, - 0,0,0,136,2,160,0,161,0,115,12,100,1,83,0,124, - 2,160,1,100,2,100,3,161,2,125,3,136,0,106,2,106, - 3,124,3,100,4,141,1,137,1,135,0,135,1,135,2,102, - 3,100,5,100,6,132,8,136,2,160,4,161,0,68,0,131, - 1,83,0,41,7,78,114,3,0,0,0,250,1,45,114,45, - 0,0,0,41,1,114,63,1,0,0,99,1,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,51, - 0,0,0,115,32,0,0,0,124,0,93,24,125,1,136,0, - 160,0,136,1,136,2,124,1,161,3,114,26,124,1,86,0, - 1,0,113,2,100,0,83,0,114,110,0,0,0,41,1,114, - 74,1,0,0,41,2,114,32,0,0,0,114,41,1,0,0, - 169,3,114,193,0,0,0,90,7,109,97,116,99,104,101,114, - 114,73,1,0,0,114,3,0,0,0,114,6,0,0,0,114, - 19,1,0,0,135,5,0,0,115,6,0,0,0,4,0,2, - 1,14,255,122,42,80,97,116,104,70,105,110,100,101,114,46, - 95,115,101,97,114,99,104,95,112,97,116,104,46,60,108,111, - 99,97,108,115,62,46,60,103,101,110,101,120,112,114,62,41, - 5,90,6,105,115,95,100,105,114,114,67,0,0,0,218,15, - 115,101,97,114,99,104,95,116,101,109,112,108,97,116,101,114, - 62,0,0,0,90,7,105,116,101,114,100,105,114,41,4,114, - 193,0,0,0,114,73,1,0,0,114,63,1,0,0,90,10, - 110,111,114,109,97,108,105,122,101,100,114,3,0,0,0,114, - 76,1,0,0,114,6,0,0,0,114,65,1,0,0,129,5, - 0,0,115,10,0,0,0,0,2,8,1,4,1,12,1,14, - 1,122,23,80,97,116,104,70,105,110,100,101,114,46,95,115, - 101,97,114,99,104,95,112,97,116,104,41,1,78,41,2,78, - 78,41,1,78,41,2,78,78,41,19,114,125,0,0,0,114, - 124,0,0,0,114,126,0,0,0,114,127,0,0,0,114,207, - 0,0,0,114,46,1,0,0,114,52,1,0,0,114,54,1, - 0,0,114,55,1,0,0,114,58,1,0,0,114,203,0,0, - 0,114,206,0,0,0,114,77,1,0,0,114,64,1,0,0, - 114,61,1,0,0,218,12,115,116,97,116,105,99,109,101,116, - 104,111,100,114,68,1,0,0,114,74,1,0,0,114,65,1, - 0,0,114,3,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,45,1,0,0,209,4,0,0,115, - 52,0,0,0,8,2,4,2,2,1,10,9,2,1,10,12, - 2,1,10,21,2,1,10,14,2,1,12,31,2,1,12,23, - 2,1,12,12,4,2,2,1,12,17,2,1,10,8,2,1, - 10,8,2,1,10,4,2,1,114,45,1,0,0,99,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,64,0,0,0,115,90,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,101,6,90,7,100,6,100,7,132, - 0,90,8,100,8,100,9,132,0,90,9,100,19,100,11,100, - 12,132,1,90,10,100,13,100,14,132,0,90,11,101,12,100, - 15,100,16,132,0,131,1,90,13,100,17,100,18,132,0,90, - 14,100,10,83,0,41,20,218,10,70,105,108,101,70,105,110, - 100,101,114,122,172,70,105,108,101,45,98,97,115,101,100,32, - 102,105,110,100,101,114,46,10,10,32,32,32,32,73,110,116, - 101,114,97,99,116,105,111,110,115,32,119,105,116,104,32,116, - 104,101,32,102,105,108,101,32,115,121,115,116,101,109,32,97, - 114,101,32,99,97,99,104,101,100,32,102,111,114,32,112,101, - 114,102,111,114,109,97,110,99,101,44,32,98,101,105,110,103, - 10,32,32,32,32,114,101,102,114,101,115,104,101,100,32,119, - 104,101,110,32,116,104,101,32,100,105,114,101,99,116,111,114, - 121,32,116,104,101,32,102,105,110,100,101,114,32,105,115,32, - 104,97,110,100,108,105,110,103,32,104,97,115,32,98,101,101, - 110,32,109,111,100,105,102,105,101,100,46,10,10,32,32,32, - 32,99,2,0,0,0,0,0,0,0,0,0,0,0,5,0, - 0,0,6,0,0,0,7,0,0,0,115,84,0,0,0,103, - 0,125,3,124,2,68,0,93,32,92,2,137,0,125,4,124, - 3,160,0,135,0,102,1,100,1,100,2,132,8,124,4,68, - 0,131,1,161,1,1,0,113,8,124,3,124,0,95,1,124, - 1,112,54,100,3,124,0,95,2,100,4,124,0,95,3,116, - 4,131,0,124,0,95,5,116,4,131,0,124,0,95,6,100, - 5,83,0,41,6,122,154,73,110,105,116,105,97,108,105,122, - 101,32,119,105,116,104,32,116,104,101,32,112,97,116,104,32, - 116,111,32,115,101,97,114,99,104,32,111,110,32,97,110,100, - 32,97,32,118,97,114,105,97,98,108,101,32,110,117,109,98, - 101,114,32,111,102,10,32,32,32,32,32,32,32,32,50,45, - 116,117,112,108,101,115,32,99,111,110,116,97,105,110,105,110, - 103,32,116,104,101,32,108,111,97,100,101,114,32,97,110,100, - 32,116,104,101,32,102,105,108,101,32,115,117,102,102,105,120, - 101,115,32,116,104,101,32,108,111,97,100,101,114,10,32,32, - 32,32,32,32,32,32,114,101,99,111,103,110,105,122,101,115, - 46,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,3,0,0,0,51,0,0,0,115,22,0,0,0,124, - 0,93,14,125,1,124,1,136,0,102,2,86,0,1,0,113, - 2,100,0,83,0,114,110,0,0,0,114,3,0,0,0,114, - 16,1,0,0,169,1,114,140,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,19,1,0,0,154,5,0,0,115,4, - 0,0,0,4,0,2,0,122,38,70,105,108,101,70,105,110, - 100,101,114,46,95,95,105,110,105,116,95,95,46,60,108,111, - 99,97,108,115,62,46,60,103,101,110,101,120,112,114,62,114, - 71,0,0,0,114,105,0,0,0,78,41,7,114,167,0,0, - 0,218,8,95,108,111,97,100,101,114,115,114,44,0,0,0, - 218,11,95,112,97,116,104,95,109,116,105,109,101,218,3,115, - 101,116,218,11,95,112,97,116,104,95,99,97,99,104,101,218, - 19,95,114,101,108,97,120,101,100,95,112,97,116,104,95,99, - 97,99,104,101,41,5,114,119,0,0,0,114,44,0,0,0, - 218,14,108,111,97,100,101,114,95,100,101,116,97,105,108,115, - 90,7,108,111,97,100,101,114,115,114,189,0,0,0,114,3, - 0,0,0,114,80,1,0,0,114,6,0,0,0,114,209,0, - 0,0,148,5,0,0,115,16,0,0,0,0,4,4,1,12, - 1,26,1,6,2,10,1,6,1,8,1,122,19,70,105,108, - 101,70,105,110,100,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,10,0,0,0,100,1, - 124,0,95,0,100,2,83,0,41,3,122,31,73,110,118,97, - 108,105,100,97,116,101,32,116,104,101,32,100,105,114,101,99, - 116,111,114,121,32,109,116,105,109,101,46,114,105,0,0,0, - 78,41,1,114,82,1,0,0,114,246,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,46,1,0, - 0,162,5,0,0,115,2,0,0,0,0,2,122,28,70,105, - 108,101,70,105,110,100,101,114,46,105,110,118,97,108,105,100, + 0,67,0,0,0,115,4,0,0,0,100,1,83,0,41,2, + 78,114,40,0,0,0,114,3,0,0,0,114,220,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 230,0,0,0,188,4,0,0,115,2,0,0,0,0,1,122, + 27,95,78,97,109,101,115,112,97,99,101,76,111,97,100,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,6,0,0, + 0,67,0,0,0,115,16,0,0,0,116,0,100,1,100,2, + 100,3,100,4,100,5,141,4,83,0,41,6,78,114,40,0, + 0,0,122,8,60,115,116,114,105,110,103,62,114,216,0,0, + 0,84,41,1,114,232,0,0,0,41,1,114,233,0,0,0, + 114,220,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,214,0,0,0,191,4,0,0,115,2,0, + 0,0,0,1,122,25,95,78,97,109,101,115,112,97,99,101, + 76,111,97,100,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,114,211,0,0,0,114,3,0,0,0,114,212,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 213,0,0,0,194,4,0,0,115,2,0,0,0,0,1,122, + 30,95,78,97,109,101,115,112,97,99,101,76,111,97,100,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, + 1,0,0,0,67,0,0,0,115,4,0,0,0,100,0,83, + 0,114,110,0,0,0,114,3,0,0,0,114,254,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 218,0,0,0,197,4,0,0,115,2,0,0,0,0,1,122, + 28,95,78,97,109,101,115,112,97,99,101,76,111,97,100,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,4,0, + 0,0,67,0,0,0,115,26,0,0,0,116,0,160,1,100, + 1,124,0,106,2,161,2,1,0,116,0,160,3,124,0,124, + 1,161,2,83,0,41,2,122,98,76,111,97,100,32,97,32, + 110,97,109,101,115,112,97,99,101,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,122,38,110,97,109, + 101,115,112,97,99,101,32,109,111,100,117,108,101,32,108,111, + 97,100,101,100,32,119,105,116,104,32,112,97,116,104,32,123, + 33,114,125,41,4,114,135,0,0,0,114,150,0,0,0,114, + 25,1,0,0,114,219,0,0,0,114,220,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,221,0, + 0,0,200,4,0,0,115,8,0,0,0,0,7,6,1,4, + 255,4,2,122,28,95,78,97,109,101,115,112,97,99,101,76, + 111,97,100,101,114,46,108,111,97,100,95,109,111,100,117,108, + 101,78,41,12,114,126,0,0,0,114,125,0,0,0,114,127, + 0,0,0,114,210,0,0,0,114,208,0,0,0,114,45,1, + 0,0,114,183,0,0,0,114,230,0,0,0,114,214,0,0, + 0,114,213,0,0,0,114,218,0,0,0,114,221,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,44,1,0,0,172,4,0,0,115,18,0, + 0,0,8,1,8,3,2,1,10,8,8,3,8,3,8,3, + 8,3,8,3,114,44,1,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,118,0,0,0,101,0,90,1,100,0,90,2,100, + 1,90,3,101,4,100,2,100,3,132,0,131,1,90,5,101, + 4,100,4,100,5,132,0,131,1,90,6,101,4,100,6,100, + 7,132,0,131,1,90,7,101,4,100,8,100,9,132,0,131, + 1,90,8,101,4,100,19,100,11,100,12,132,1,131,1,90, + 9,101,4,100,20,100,13,100,14,132,1,131,1,90,10,101, + 4,100,21,100,15,100,16,132,1,131,1,90,11,101,4,100, + 17,100,18,132,0,131,1,90,12,100,10,83,0,41,22,218, + 10,80,97,116,104,70,105,110,100,101,114,122,62,77,101,116, + 97,32,112,97,116,104,32,102,105,110,100,101,114,32,102,111, + 114,32,115,121,115,46,112,97,116,104,32,97,110,100,32,112, + 97,99,107,97,103,101,32,95,95,112,97,116,104,95,95,32, + 97,116,116,114,105,98,117,116,101,115,46,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,116,0,116,1,106,2,160, + 3,161,0,131,1,68,0,93,44,92,2,125,1,125,2,124, + 2,100,1,107,8,114,40,116,1,106,2,124,1,61,0,113, + 14,116,4,124,2,100,2,131,2,114,14,124,2,160,5,161, + 0,1,0,113,14,100,1,83,0,41,3,122,125,67,97,108, + 108,32,116,104,101,32,105,110,118,97,108,105,100,97,116,101, + 95,99,97,99,104,101,115,40,41,32,109,101,116,104,111,100, + 32,111,110,32,97,108,108,32,112,97,116,104,32,101,110,116, + 114,121,32,102,105,110,100,101,114,115,10,32,32,32,32,32, + 32,32,32,115,116,111,114,101,100,32,105,110,32,115,121,115, + 46,112,97,116,104,95,105,109,112,111,114,116,101,114,95,99, + 97,99,104,101,115,32,40,119,104,101,114,101,32,105,109,112, + 108,101,109,101,110,116,101,100,41,46,78,218,17,105,110,118, + 97,108,105,100,97,116,101,95,99,97,99,104,101,115,41,6, + 218,4,108,105,115,116,114,8,0,0,0,218,19,112,97,116, + 104,95,105,109,112,111,114,116,101,114,95,99,97,99,104,101, + 218,5,105,116,101,109,115,114,129,0,0,0,114,47,1,0, + 0,41,3,114,194,0,0,0,114,117,0,0,0,218,6,102, + 105,110,100,101,114,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,47,1,0,0,218,4,0,0,115,10,0, + 0,0,0,4,22,1,8,1,10,1,10,1,122,28,80,97, + 116,104,70,105,110,100,101,114,46,105,110,118,97,108,105,100, 97,116,101,95,99,97,99,104,101,115,99,2,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, - 0,0,0,115,42,0,0,0,124,0,160,0,124,1,161,1, - 125,2,124,2,100,1,107,8,114,26,100,1,103,0,102,2, - 83,0,124,2,106,1,124,2,106,2,112,38,103,0,102,2, - 83,0,41,2,122,197,84,114,121,32,116,111,32,102,105,110, - 100,32,97,32,108,111,97,100,101,114,32,102,111,114,32,116, - 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, - 117,108,101,44,32,111,114,32,116,104,101,32,110,97,109,101, - 115,112,97,99,101,10,32,32,32,32,32,32,32,32,112,97, - 99,107,97,103,101,32,112,111,114,116,105,111,110,115,46,32, - 82,101,116,117,114,110,115,32,40,108,111,97,100,101,114,44, - 32,108,105,115,116,45,111,102,45,112,111,114,116,105,111,110, - 115,41,46,10,10,32,32,32,32,32,32,32,32,84,104,105, + 0,0,0,0,0,0,0,3,0,0,0,9,0,0,0,67, + 0,0,0,115,84,0,0,0,116,0,106,1,100,1,107,9, + 114,28,116,0,106,1,115,28,116,2,160,3,100,2,116,4, + 161,2,1,0,116,0,106,1,68,0,93,44,125,2,122,14, + 124,2,124,1,131,1,87,0,2,0,1,0,83,0,4,0, + 116,5,107,10,114,76,1,0,1,0,1,0,89,0,113,34, + 89,0,113,34,88,0,113,34,100,1,83,0,41,3,122,46, + 83,101,97,114,99,104,32,115,121,115,46,112,97,116,104,95, + 104,111,111,107,115,32,102,111,114,32,97,32,102,105,110,100, + 101,114,32,102,111,114,32,39,112,97,116,104,39,46,78,122, + 23,115,121,115,46,112,97,116,104,95,104,111,111,107,115,32, + 105,115,32,101,109,112,116,121,41,6,114,8,0,0,0,218, + 10,112,97,116,104,95,104,111,111,107,115,114,75,0,0,0, + 114,76,0,0,0,114,139,0,0,0,114,118,0,0,0,41, + 3,114,194,0,0,0,114,44,0,0,0,90,4,104,111,111, + 107,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 218,11,95,112,97,116,104,95,104,111,111,107,115,228,4,0, + 0,115,16,0,0,0,0,3,16,1,12,1,10,1,2,1, + 14,1,14,1,12,2,122,22,80,97,116,104,70,105,110,100, + 101,114,46,95,112,97,116,104,95,104,111,111,107,115,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,104,0,0,0,124,1,100,1, + 107,2,114,44,122,12,116,0,160,1,161,0,125,1,87,0, + 110,22,4,0,116,2,107,10,114,42,1,0,1,0,1,0, + 89,0,100,2,83,0,88,0,122,14,116,3,106,4,124,1, + 25,0,125,2,87,0,110,40,4,0,116,5,107,10,114,98, + 1,0,1,0,1,0,124,0,160,6,124,1,161,1,125,2, + 124,2,116,3,106,4,124,1,60,0,89,0,110,2,88,0, + 124,2,83,0,41,3,122,210,71,101,116,32,116,104,101,32, + 102,105,110,100,101,114,32,102,111,114,32,116,104,101,32,112, + 97,116,104,32,101,110,116,114,121,32,102,114,111,109,32,115, + 121,115,46,112,97,116,104,95,105,109,112,111,114,116,101,114, + 95,99,97,99,104,101,46,10,10,32,32,32,32,32,32,32, + 32,73,102,32,116,104,101,32,112,97,116,104,32,101,110,116, + 114,121,32,105,115,32,110,111,116,32,105,110,32,116,104,101, + 32,99,97,99,104,101,44,32,102,105,110,100,32,116,104,101, + 32,97,112,112,114,111,112,114,105,97,116,101,32,102,105,110, + 100,101,114,10,32,32,32,32,32,32,32,32,97,110,100,32, + 99,97,99,104,101,32,105,116,46,32,73,102,32,110,111,32, + 102,105,110,100,101,114,32,105,115,32,97,118,97,105,108,97, + 98,108,101,44,32,115,116,111,114,101,32,78,111,110,101,46, + 10,10,32,32,32,32,32,32,32,32,114,40,0,0,0,78, + 41,7,114,2,0,0,0,114,55,0,0,0,114,4,1,0, + 0,114,8,0,0,0,114,49,1,0,0,218,8,75,101,121, + 69,114,114,111,114,114,53,1,0,0,41,3,114,194,0,0, + 0,114,44,0,0,0,114,51,1,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,20,95,112,97,116, + 104,95,105,109,112,111,114,116,101,114,95,99,97,99,104,101, + 241,4,0,0,115,22,0,0,0,0,8,8,1,2,1,12, + 1,14,3,8,1,2,1,14,1,14,1,10,1,16,1,122, + 31,80,97,116,104,70,105,110,100,101,114,46,95,112,97,116, + 104,95,105,109,112,111,114,116,101,114,95,99,97,99,104,101, + 99,3,0,0,0,0,0,0,0,0,0,0,0,6,0,0, + 0,4,0,0,0,67,0,0,0,115,82,0,0,0,116,0, + 124,2,100,1,131,2,114,26,124,2,160,1,124,1,161,1, + 92,2,125,3,125,4,110,14,124,2,160,2,124,1,161,1, + 125,3,103,0,125,4,124,3,100,0,107,9,114,60,116,3, + 160,4,124,1,124,3,161,2,83,0,116,3,160,5,124,1, + 100,0,161,2,125,5,124,4,124,5,95,6,124,5,83,0, + 41,2,78,114,138,0,0,0,41,7,114,129,0,0,0,114, + 138,0,0,0,114,207,0,0,0,114,135,0,0,0,114,202, + 0,0,0,114,184,0,0,0,114,179,0,0,0,41,6,114, + 194,0,0,0,114,140,0,0,0,114,51,1,0,0,114,141, + 0,0,0,114,142,0,0,0,114,188,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,16,95,108, + 101,103,97,99,121,95,103,101,116,95,115,112,101,99,7,5, + 0,0,115,18,0,0,0,0,4,10,1,16,2,10,1,4, + 1,8,1,12,1,12,1,6,1,122,27,80,97,116,104,70, + 105,110,100,101,114,46,95,108,101,103,97,99,121,95,103,101, + 116,95,115,112,101,99,78,99,4,0,0,0,0,0,0,0, + 0,0,0,0,9,0,0,0,5,0,0,0,67,0,0,0, + 115,166,0,0,0,103,0,125,4,124,2,68,0,93,134,125, + 5,116,0,124,5,116,1,116,2,102,2,131,2,115,28,113, + 8,124,0,160,3,124,5,161,1,125,6,124,6,100,1,107, + 9,114,8,116,4,124,6,100,2,131,2,114,70,124,6,160, + 5,124,1,124,3,161,2,125,7,110,12,124,0,160,6,124, + 1,124,6,161,2,125,7,124,7,100,1,107,8,114,92,113, + 8,124,7,106,7,100,1,107,9,114,110,124,7,2,0,1, + 0,83,0,124,7,106,8,125,8,124,8,100,1,107,8,114, + 132,116,9,100,3,131,1,130,1,124,4,160,10,124,8,161, + 1,1,0,113,8,116,11,160,12,124,1,100,1,161,2,125, + 7,124,4,124,7,95,8,124,7,83,0,41,4,122,63,70, + 105,110,100,32,116,104,101,32,108,111,97,100,101,114,32,111, + 114,32,110,97,109,101,115,112,97,99,101,95,112,97,116,104, + 32,102,111,114,32,116,104,105,115,32,109,111,100,117,108,101, + 47,112,97,99,107,97,103,101,32,110,97,109,101,46,78,114, + 204,0,0,0,122,19,115,112,101,99,32,109,105,115,115,105, + 110,103,32,108,111,97,100,101,114,41,13,114,162,0,0,0, + 114,85,0,0,0,218,5,98,121,116,101,115,114,55,1,0, + 0,114,129,0,0,0,114,204,0,0,0,114,56,1,0,0, + 114,141,0,0,0,114,179,0,0,0,114,118,0,0,0,114, + 168,0,0,0,114,135,0,0,0,114,184,0,0,0,41,9, + 114,194,0,0,0,114,140,0,0,0,114,44,0,0,0,114, + 203,0,0,0,218,14,110,97,109,101,115,112,97,99,101,95, + 112,97,116,104,90,5,101,110,116,114,121,114,51,1,0,0, + 114,188,0,0,0,114,142,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,9,95,103,101,116,95, + 115,112,101,99,22,5,0,0,115,40,0,0,0,0,5,4, + 1,8,1,14,1,2,1,10,1,8,1,10,1,14,2,12, + 1,8,1,2,1,10,1,8,1,6,1,8,1,8,5,12, + 2,12,1,6,1,122,20,80,97,116,104,70,105,110,100,101, + 114,46,95,103,101,116,95,115,112,101,99,99,4,0,0,0, + 0,0,0,0,0,0,0,0,6,0,0,0,5,0,0,0, + 67,0,0,0,115,100,0,0,0,124,2,100,1,107,8,114, + 14,116,0,106,1,125,2,124,0,160,2,124,1,124,2,124, + 3,161,3,125,4,124,4,100,1,107,8,114,40,100,1,83, + 0,124,4,106,3,100,1,107,8,114,92,124,4,106,4,125, + 5,124,5,114,86,100,1,124,4,95,5,116,6,124,1,124, + 5,124,0,106,2,131,3,124,4,95,4,124,4,83,0,100, + 1,83,0,110,4,124,4,83,0,100,1,83,0,41,2,122, + 141,84,114,121,32,116,111,32,102,105,110,100,32,97,32,115, + 112,101,99,32,102,111,114,32,39,102,117,108,108,110,97,109, + 101,39,32,111,110,32,115,121,115,46,112,97,116,104,32,111, + 114,32,39,112,97,116,104,39,46,10,10,32,32,32,32,32, + 32,32,32,84,104,101,32,115,101,97,114,99,104,32,105,115, + 32,98,97,115,101,100,32,111,110,32,115,121,115,46,112,97, + 116,104,95,104,111,111,107,115,32,97,110,100,32,115,121,115, + 46,112,97,116,104,95,105,109,112,111,114,116,101,114,95,99, + 97,99,104,101,46,10,32,32,32,32,32,32,32,32,78,41, + 7,114,8,0,0,0,114,44,0,0,0,114,59,1,0,0, + 114,141,0,0,0,114,179,0,0,0,114,182,0,0,0,114, + 23,1,0,0,41,6,114,194,0,0,0,114,140,0,0,0, + 114,44,0,0,0,114,203,0,0,0,114,188,0,0,0,114, + 58,1,0,0,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,114,204,0,0,0,54,5,0,0,115,26,0,0, + 0,0,6,8,1,6,1,14,1,8,1,4,1,10,1,6, + 1,4,3,6,1,16,1,4,2,6,2,122,20,80,97,116, + 104,70,105,110,100,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, + 8,114,24,100,1,83,0,124,3,106,1,83,0,41,2,122, + 170,102,105,110,100,32,116,104,101,32,109,111,100,117,108,101, + 32,111,110,32,115,121,115,46,112,97,116,104,32,111,114,32, + 39,112,97,116,104,39,32,98,97,115,101,100,32,111,110,32, + 115,121,115,46,112,97,116,104,95,104,111,111,107,115,32,97, + 110,100,10,32,32,32,32,32,32,32,32,115,121,115,46,112, + 97,116,104,95,105,109,112,111,114,116,101,114,95,99,97,99, + 104,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,3,114,203, - 0,0,0,114,140,0,0,0,114,178,0,0,0,41,3,114, - 119,0,0,0,114,139,0,0,0,114,187,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,137,0, - 0,0,168,5,0,0,115,8,0,0,0,0,7,10,1,8, - 1,8,1,122,22,70,105,108,101,70,105,110,100,101,114,46, - 102,105,110,100,95,108,111,97,100,101,114,99,6,0,0,0, - 0,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0, - 67,0,0,0,115,26,0,0,0,124,1,124,2,124,3,131, - 2,125,6,116,0,124,2,124,3,124,6,124,4,100,1,141, - 4,83,0,41,2,78,114,177,0,0,0,41,1,114,190,0, - 0,0,41,7,114,119,0,0,0,114,188,0,0,0,114,139, - 0,0,0,114,44,0,0,0,90,4,115,109,115,108,114,202, - 0,0,0,114,140,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,58,1,0,0,180,5,0,0, - 115,8,0,0,0,0,1,10,1,8,1,2,255,122,20,70, - 105,108,101,70,105,110,100,101,114,46,95,103,101,116,95,115, - 112,101,99,78,99,3,0,0,0,0,0,0,0,0,0,0, - 0,14,0,0,0,8,0,0,0,67,0,0,0,115,102,1, - 0,0,100,1,125,3,124,1,160,0,100,2,161,1,100,3, - 25,0,125,4,122,24,116,1,124,0,106,2,112,34,116,3, - 160,4,161,0,131,1,106,5,125,5,87,0,110,24,4,0, - 116,6,107,10,114,66,1,0,1,0,1,0,100,4,125,5, - 89,0,110,2,88,0,124,5,124,0,106,7,107,3,114,92, - 124,0,160,8,161,0,1,0,124,5,124,0,95,7,116,9, - 131,0,114,114,124,0,106,10,125,6,124,4,160,11,161,0, - 125,7,110,10,124,0,106,12,125,6,124,4,125,7,124,7, - 124,6,107,6,114,218,116,13,124,0,106,2,124,4,131,2, - 125,8,124,0,106,14,68,0,93,58,92,2,125,9,125,10, - 100,5,124,9,23,0,125,11,116,13,124,8,124,11,131,2, - 125,12,116,15,124,12,131,1,114,208,124,0,160,16,124,10, - 124,1,124,12,124,8,103,1,124,2,161,5,2,0,1,0, - 83,0,113,150,116,17,124,8,131,1,125,3,124,0,106,14, - 68,0,93,86,92,2,125,9,125,10,116,13,124,0,106,2, - 124,4,124,9,23,0,131,2,125,12,116,18,106,19,100,6, - 124,12,100,3,100,7,141,3,1,0,124,7,124,9,23,0, - 124,6,107,6,144,1,114,54,116,15,124,12,131,1,144,1, - 114,54,124,0,160,16,124,10,124,1,124,12,100,8,124,2, - 161,5,2,0,1,0,83,0,113,224,124,3,144,1,114,98, - 116,18,160,19,100,9,124,8,161,2,1,0,116,18,160,20, - 124,1,100,8,161,2,125,13,124,8,103,1,124,13,95,21, - 124,13,83,0,100,8,83,0,41,10,122,111,84,114,121,32, - 116,111,32,102,105,110,100,32,97,32,115,112,101,99,32,102, - 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 32,109,111,100,117,108,101,46,10,10,32,32,32,32,32,32, - 32,32,82,101,116,117,114,110,115,32,116,104,101,32,109,97, - 116,99,104,105,110,103,32,115,112,101,99,44,32,111,114,32, - 78,111,110,101,32,105,102,32,110,111,116,32,102,111,117,110, - 100,46,10,32,32,32,32,32,32,32,32,70,114,71,0,0, - 0,114,28,0,0,0,114,105,0,0,0,114,209,0,0,0, - 122,9,116,114,121,105,110,103,32,123,125,41,1,90,9,118, - 101,114,98,111,115,105,116,121,78,122,25,112,111,115,115,105, - 98,108,101,32,110,97,109,101,115,112,97,99,101,32,102,111, - 114,32,123,125,41,22,114,41,0,0,0,114,49,0,0,0, - 114,44,0,0,0,114,2,0,0,0,114,55,0,0,0,114, - 10,1,0,0,114,50,0,0,0,114,82,1,0,0,218,11, - 95,102,105,108,108,95,99,97,99,104,101,114,7,0,0,0, - 114,85,1,0,0,114,106,0,0,0,114,84,1,0,0,114, - 38,0,0,0,114,81,1,0,0,114,54,0,0,0,114,58, - 1,0,0,114,56,0,0,0,114,134,0,0,0,114,149,0, - 0,0,114,183,0,0,0,114,178,0,0,0,41,14,114,119, - 0,0,0,114,139,0,0,0,114,202,0,0,0,90,12,105, - 115,95,110,97,109,101,115,112,97,99,101,90,11,116,97,105, - 108,95,109,111,100,117,108,101,114,169,0,0,0,90,5,99, - 97,99,104,101,90,12,99,97,99,104,101,95,109,111,100,117, - 108,101,90,9,98,97,115,101,95,112,97,116,104,114,17,1, - 0,0,114,188,0,0,0,90,13,105,110,105,116,95,102,105, - 108,101,110,97,109,101,90,9,102,117,108,108,95,112,97,116, - 104,114,187,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,203,0,0,0,185,5,0,0,115,74, - 0,0,0,0,5,4,1,14,1,2,1,24,1,14,1,10, - 1,10,1,8,1,6,2,6,1,6,1,10,2,6,1,4, - 2,8,1,12,1,14,1,8,1,10,1,8,1,26,4,8, - 2,14,1,16,1,16,1,14,1,10,1,10,1,2,0,2, - 255,10,2,6,1,12,1,12,1,8,1,4,1,122,20,70, - 105,108,101,70,105,110,100,101,114,46,102,105,110,100,95,115, - 112,101,99,99,1,0,0,0,0,0,0,0,0,0,0,0, - 9,0,0,0,10,0,0,0,67,0,0,0,115,190,0,0, - 0,124,0,106,0,125,1,122,22,116,1,160,2,124,1,112, - 22,116,1,160,3,161,0,161,1,125,2,87,0,110,30,4, - 0,116,4,116,5,116,6,102,3,107,10,114,58,1,0,1, - 0,1,0,103,0,125,2,89,0,110,2,88,0,116,7,106, - 8,160,9,100,1,161,1,115,84,116,10,124,2,131,1,124, - 0,95,11,110,74,116,10,131,0,125,3,124,2,68,0,93, - 56,125,4,124,4,160,12,100,2,161,1,92,3,125,5,125, - 6,125,7,124,6,114,136,100,3,160,13,124,5,124,7,160, - 14,161,0,161,2,125,8,110,4,124,5,125,8,124,3,160, - 15,124,8,161,1,1,0,113,94,124,3,124,0,95,11,116, - 7,106,8,160,9,116,16,161,1,114,186,100,4,100,5,132, - 0,124,2,68,0,131,1,124,0,95,17,100,6,83,0,41, - 7,122,68,70,105,108,108,32,116,104,101,32,99,97,99,104, - 101,32,111,102,32,112,111,116,101,110,116,105,97,108,32,109, - 111,100,117,108,101,115,32,97,110,100,32,112,97,99,107,97, - 103,101,115,32,102,111,114,32,116,104,105,115,32,100,105,114, - 101,99,116,111,114,121,46,114,0,0,0,0,114,71,0,0, - 0,114,61,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,4,0,0,0,83,0,0,0,115, - 20,0,0,0,104,0,124,0,93,12,125,1,124,1,160,0, - 161,0,146,2,113,4,83,0,114,3,0,0,0,41,1,114, - 106,0,0,0,41,2,114,32,0,0,0,90,2,102,110,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,9, - 60,115,101,116,99,111,109,112,62,6,6,0,0,115,4,0, - 0,0,6,0,2,0,122,41,70,105,108,101,70,105,110,100, - 101,114,46,95,102,105,108,108,95,99,97,99,104,101,46,60, - 108,111,99,97,108,115,62,46,60,115,101,116,99,111,109,112, - 62,78,41,18,114,44,0,0,0,114,2,0,0,0,114,7, - 1,0,0,114,55,0,0,0,114,3,1,0,0,218,15,80, - 101,114,109,105,115,115,105,111,110,69,114,114,111,114,218,18, - 78,111,116,65,68,105,114,101,99,116,111,114,121,69,114,114, - 111,114,114,8,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,83,1,0,0,114,84,1,0,0,114,101,0,0,0, - 114,62,0,0,0,114,106,0,0,0,218,3,97,100,100,114, - 11,0,0,0,114,85,1,0,0,41,9,114,119,0,0,0, - 114,44,0,0,0,114,8,1,0,0,90,21,108,111,119,101, - 114,95,115,117,102,102,105,120,95,99,111,110,116,101,110,116, - 115,114,41,1,0,0,114,117,0,0,0,114,29,1,0,0, - 114,17,1,0,0,90,8,110,101,119,95,110,97,109,101,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,87, - 1,0,0,233,5,0,0,115,34,0,0,0,0,2,6,1, - 2,1,22,1,20,3,10,3,12,1,12,7,6,1,8,1, - 16,1,4,1,18,2,4,1,12,1,6,1,12,1,122,22, - 70,105,108,101,70,105,110,100,101,114,46,95,102,105,108,108, - 95,99,97,99,104,101,99,1,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,3,0,0,0,7,0,0,0,115, - 18,0,0,0,135,0,135,1,102,2,100,1,100,2,132,8, - 125,2,124,2,83,0,41,3,97,20,1,0,0,65,32,99, - 108,97,115,115,32,109,101,116,104,111,100,32,119,104,105,99, - 104,32,114,101,116,117,114,110,115,32,97,32,99,108,111,115, - 117,114,101,32,116,111,32,117,115,101,32,111,110,32,115,121, - 115,46,112,97,116,104,95,104,111,111,107,10,32,32,32,32, - 32,32,32,32,119,104,105,99,104,32,119,105,108,108,32,114, - 101,116,117,114,110,32,97,110,32,105,110,115,116,97,110,99, - 101,32,117,115,105,110,103,32,116,104,101,32,115,112,101,99, - 105,102,105,101,100,32,108,111,97,100,101,114,115,32,97,110, - 100,32,116,104,101,32,112,97,116,104,10,32,32,32,32,32, - 32,32,32,99,97,108,108,101,100,32,111,110,32,116,104,101, - 32,99,108,111,115,117,114,101,46,10,10,32,32,32,32,32, - 32,32,32,73,102,32,116,104,101,32,112,97,116,104,32,99, - 97,108,108,101,100,32,111,110,32,116,104,101,32,99,108,111, - 115,117,114,101,32,105,115,32,110,111,116,32,97,32,100,105, - 114,101,99,116,111,114,121,44,32,73,109,112,111,114,116,69, - 114,114,111,114,32,105,115,10,32,32,32,32,32,32,32,32, - 114,97,105,115,101,100,46,10,10,32,32,32,32,32,32,32, - 32,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,4,0,0,0,19,0,0,0,115,34,0,0,0,116, - 0,124,0,131,1,115,20,116,1,100,1,124,0,100,2,141, - 2,130,1,136,0,124,0,102,1,136,1,158,2,142,0,83, - 0,41,3,122,45,80,97,116,104,32,104,111,111,107,32,102, - 111,114,32,105,109,112,111,114,116,108,105,98,46,109,97,99, - 104,105,110,101,114,121,46,70,105,108,101,70,105,110,100,101, - 114,46,122,30,111,110,108,121,32,100,105,114,101,99,116,111, - 114,105,101,115,32,97,114,101,32,115,117,112,112,111,114,116, - 101,100,114,48,0,0,0,41,2,114,56,0,0,0,114,118, - 0,0,0,114,48,0,0,0,169,2,114,193,0,0,0,114, - 86,1,0,0,114,3,0,0,0,114,6,0,0,0,218,24, - 112,97,116,104,95,104,111,111,107,95,102,111,114,95,70,105, - 108,101,70,105,110,100,101,114,18,6,0,0,115,6,0,0, - 0,0,2,8,1,12,1,122,54,70,105,108,101,70,105,110, - 100,101,114,46,112,97,116,104,95,104,111,111,107,46,60,108, - 111,99,97,108,115,62,46,112,97,116,104,95,104,111,111,107, - 95,102,111,114,95,70,105,108,101,70,105,110,100,101,114,114, - 3,0,0,0,41,3,114,193,0,0,0,114,86,1,0,0, - 114,93,1,0,0,114,3,0,0,0,114,92,1,0,0,114, - 6,0,0,0,218,9,112,97,116,104,95,104,111,111,107,8, - 6,0,0,115,4,0,0,0,0,10,14,6,122,20,70,105, - 108,101,70,105,110,100,101,114,46,112,97,116,104,95,104,111, - 111,107,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,12,0,0,0, - 100,1,160,0,124,0,106,1,161,1,83,0,41,2,78,122, - 16,70,105,108,101,70,105,110,100,101,114,40,123,33,114,125, - 41,41,2,114,62,0,0,0,114,44,0,0,0,114,246,0, + 46,10,10,32,32,32,32,32,32,32,32,78,114,205,0,0, + 0,114,206,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,207,0,0,0,78,5,0,0,115,8, + 0,0,0,0,8,12,1,8,1,4,1,122,22,80,97,116, + 104,70,105,110,100,101,114,46,102,105,110,100,95,109,111,100, + 117,108,101,99,1,0,0,0,0,0,0,0,0,0,0,0, + 4,0,0,0,3,0,0,0,79,0,0,0,115,24,0,0, + 0,100,1,100,2,108,0,109,1,125,3,1,0,124,3,106, + 2,124,1,124,2,142,1,83,0,41,3,97,32,1,0,0, + 10,32,32,32,32,32,32,32,32,70,105,110,100,32,100,105, + 115,116,114,105,98,117,116,105,111,110,115,46,10,10,32,32, + 32,32,32,32,32,32,82,101,116,117,114,110,32,97,110,32, + 105,116,101,114,97,98,108,101,32,111,102,32,97,108,108,32, + 68,105,115,116,114,105,98,117,116,105,111,110,32,105,110,115, + 116,97,110,99,101,115,32,99,97,112,97,98,108,101,32,111, + 102,10,32,32,32,32,32,32,32,32,108,111,97,100,105,110, + 103,32,116,104,101,32,109,101,116,97,100,97,116,97,32,102, + 111,114,32,112,97,99,107,97,103,101,115,32,109,97,116,99, + 104,105,110,103,32,96,96,99,111,110,116,101,120,116,46,110, + 97,109,101,96,96,10,32,32,32,32,32,32,32,32,40,111, + 114,32,97,108,108,32,110,97,109,101,115,32,105,102,32,96, + 96,78,111,110,101,96,96,32,105,110,100,105,99,97,116,101, + 100,41,32,97,108,111,110,103,32,116,104,101,32,112,97,116, + 104,115,32,105,110,32,116,104,101,32,108,105,115,116,10,32, + 32,32,32,32,32,32,32,111,102,32,100,105,114,101,99,116, + 111,114,105,101,115,32,96,96,99,111,110,116,101,120,116,46, + 112,97,116,104,96,96,46,10,32,32,32,32,32,32,32,32, + 114,73,0,0,0,41,1,218,18,77,101,116,97,100,97,116, + 97,80,97,116,104,70,105,110,100,101,114,41,3,90,18,105, + 109,112,111,114,116,108,105,98,46,109,101,116,97,100,97,116, + 97,114,60,1,0,0,218,18,102,105,110,100,95,100,105,115, + 116,114,105,98,117,116,105,111,110,115,41,4,114,194,0,0, + 0,114,120,0,0,0,114,121,0,0,0,114,60,1,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 61,1,0,0,91,5,0,0,115,4,0,0,0,0,10,12, + 1,122,29,80,97,116,104,70,105,110,100,101,114,46,102,105, + 110,100,95,100,105,115,116,114,105,98,117,116,105,111,110,115, + 41,1,78,41,2,78,78,41,1,78,41,13,114,126,0,0, + 0,114,125,0,0,0,114,127,0,0,0,114,128,0,0,0, + 114,208,0,0,0,114,47,1,0,0,114,53,1,0,0,114, + 55,1,0,0,114,56,1,0,0,114,59,1,0,0,114,204, + 0,0,0,114,207,0,0,0,114,61,1,0,0,114,3,0, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,39,1,0,0,26,6,0,0,115,2,0,0,0,0, - 1,122,19,70,105,108,101,70,105,110,100,101,114,46,95,95, - 114,101,112,114,95,95,41,1,78,41,15,114,125,0,0,0, - 114,124,0,0,0,114,126,0,0,0,114,127,0,0,0,114, - 209,0,0,0,114,46,1,0,0,114,143,0,0,0,114,206, - 0,0,0,114,137,0,0,0,114,58,1,0,0,114,203,0, - 0,0,114,87,1,0,0,114,207,0,0,0,114,94,1,0, - 0,114,39,1,0,0,114,3,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,79,1,0,0,139, - 5,0,0,115,22,0,0,0,8,2,4,7,8,14,8,4, - 4,2,8,12,8,5,10,48,8,31,2,1,10,17,114,79, - 1,0,0,99,4,0,0,0,0,0,0,0,0,0,0,0, - 6,0,0,0,8,0,0,0,67,0,0,0,115,146,0,0, - 0,124,0,160,0,100,1,161,1,125,4,124,0,160,0,100, - 2,161,1,125,5,124,4,115,66,124,5,114,36,124,5,106, - 1,125,4,110,30,124,2,124,3,107,2,114,56,116,2,124, - 1,124,2,131,2,125,4,110,10,116,3,124,1,124,2,131, - 2,125,4,124,5,115,84,116,4,124,1,124,2,124,4,100, - 3,141,3,125,5,122,36,124,5,124,0,100,2,60,0,124, - 4,124,0,100,1,60,0,124,2,124,0,100,4,60,0,124, - 3,124,0,100,5,60,0,87,0,110,20,4,0,116,5,107, - 10,114,140,1,0,1,0,1,0,89,0,110,2,88,0,100, - 0,83,0,41,6,78,218,10,95,95,108,111,97,100,101,114, - 95,95,218,8,95,95,115,112,101,99,95,95,114,80,1,0, - 0,90,8,95,95,102,105,108,101,95,95,90,10,95,95,99, - 97,99,104,101,100,95,95,41,6,218,3,103,101,116,114,140, - 0,0,0,114,15,1,0,0,114,9,1,0,0,114,190,0, - 0,0,114,72,1,0,0,41,6,90,2,110,115,114,117,0, - 0,0,90,8,112,97,116,104,110,97,109,101,90,9,99,112, - 97,116,104,110,97,109,101,114,140,0,0,0,114,187,0,0, + 0,114,46,1,0,0,214,4,0,0,115,34,0,0,0,8, + 2,4,2,2,1,10,9,2,1,10,12,2,1,10,21,2, + 1,10,14,2,1,12,31,2,1,12,23,2,1,12,12,2, + 1,114,46,1,0,0,99,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,64,0,0,0,115, + 90,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, + 101,6,90,7,100,6,100,7,132,0,90,8,100,8,100,9, + 132,0,90,9,100,19,100,11,100,12,132,1,90,10,100,13, + 100,14,132,0,90,11,101,12,100,15,100,16,132,0,131,1, + 90,13,100,17,100,18,132,0,90,14,100,10,83,0,41,20, + 218,10,70,105,108,101,70,105,110,100,101,114,122,172,70,105, + 108,101,45,98,97,115,101,100,32,102,105,110,100,101,114,46, + 10,10,32,32,32,32,73,110,116,101,114,97,99,116,105,111, + 110,115,32,119,105,116,104,32,116,104,101,32,102,105,108,101, + 32,115,121,115,116,101,109,32,97,114,101,32,99,97,99,104, + 101,100,32,102,111,114,32,112,101,114,102,111,114,109,97,110, + 99,101,44,32,98,101,105,110,103,10,32,32,32,32,114,101, + 102,114,101,115,104,101,100,32,119,104,101,110,32,116,104,101, + 32,100,105,114,101,99,116,111,114,121,32,116,104,101,32,102, + 105,110,100,101,114,32,105,115,32,104,97,110,100,108,105,110, + 103,32,104,97,115,32,98,101,101,110,32,109,111,100,105,102, + 105,101,100,46,10,10,32,32,32,32,99,2,0,0,0,0, + 0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,7, + 0,0,0,115,84,0,0,0,103,0,125,3,124,2,68,0, + 93,32,92,2,137,0,125,4,124,3,160,0,135,0,102,1, + 100,1,100,2,132,8,124,4,68,0,131,1,161,1,1,0, + 113,8,124,3,124,0,95,1,124,1,112,54,100,3,124,0, + 95,2,100,4,124,0,95,3,116,4,131,0,124,0,95,5, + 116,4,131,0,124,0,95,6,100,5,83,0,41,6,122,154, + 73,110,105,116,105,97,108,105,122,101,32,119,105,116,104,32, + 116,104,101,32,112,97,116,104,32,116,111,32,115,101,97,114, + 99,104,32,111,110,32,97,110,100,32,97,32,118,97,114,105, + 97,98,108,101,32,110,117,109,98,101,114,32,111,102,10,32, + 32,32,32,32,32,32,32,50,45,116,117,112,108,101,115,32, + 99,111,110,116,97,105,110,105,110,103,32,116,104,101,32,108, + 111,97,100,101,114,32,97,110,100,32,116,104,101,32,102,105, + 108,101,32,115,117,102,102,105,120,101,115,32,116,104,101,32, + 108,111,97,100,101,114,10,32,32,32,32,32,32,32,32,114, + 101,99,111,103,110,105,122,101,115,46,99,1,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,51, + 0,0,0,115,22,0,0,0,124,0,93,14,125,1,124,1, + 136,0,102,2,86,0,1,0,113,2,100,0,83,0,114,110, + 0,0,0,114,3,0,0,0,114,17,1,0,0,169,1,114, + 141,0,0,0,114,3,0,0,0,114,6,0,0,0,114,20, + 1,0,0,120,5,0,0,115,4,0,0,0,4,0,2,0, + 122,38,70,105,108,101,70,105,110,100,101,114,46,95,95,105, + 110,105,116,95,95,46,60,108,111,99,97,108,115,62,46,60, + 103,101,110,101,120,112,114,62,114,71,0,0,0,114,105,0, + 0,0,78,41,7,114,168,0,0,0,218,8,95,108,111,97, + 100,101,114,115,114,44,0,0,0,218,11,95,112,97,116,104, + 95,109,116,105,109,101,218,3,115,101,116,218,11,95,112,97, + 116,104,95,99,97,99,104,101,218,19,95,114,101,108,97,120, + 101,100,95,112,97,116,104,95,99,97,99,104,101,41,5,114, + 119,0,0,0,114,44,0,0,0,218,14,108,111,97,100,101, + 114,95,100,101,116,97,105,108,115,90,7,108,111,97,100,101, + 114,115,114,190,0,0,0,114,3,0,0,0,114,63,1,0, + 0,114,6,0,0,0,114,210,0,0,0,114,5,0,0,115, + 16,0,0,0,0,4,4,1,12,1,26,1,6,2,10,1, + 6,1,8,1,122,19,70,105,108,101,70,105,110,100,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,10,0,0,0,100,1,124,0,95,0,100,2,83, + 0,41,3,122,31,73,110,118,97,108,105,100,97,116,101,32, + 116,104,101,32,100,105,114,101,99,116,111,114,121,32,109,116, + 105,109,101,46,114,105,0,0,0,78,41,1,114,65,1,0, + 0,114,247,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,47,1,0,0,128,5,0,0,115,2, + 0,0,0,0,2,122,28,70,105,108,101,70,105,110,100,101, + 114,46,105,110,118,97,108,105,100,97,116,101,95,99,97,99, + 104,101,115,99,2,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,3,0,0,0,67,0,0,0,115,42,0,0, + 0,124,0,160,0,124,1,161,1,125,2,124,2,100,1,107, + 8,114,26,100,1,103,0,102,2,83,0,124,2,106,1,124, + 2,106,2,112,38,103,0,102,2,83,0,41,2,122,197,84, + 114,121,32,116,111,32,102,105,110,100,32,97,32,108,111,97, + 100,101,114,32,102,111,114,32,116,104,101,32,115,112,101,99, + 105,102,105,101,100,32,109,111,100,117,108,101,44,32,111,114, + 32,116,104,101,32,110,97,109,101,115,112,97,99,101,10,32, + 32,32,32,32,32,32,32,112,97,99,107,97,103,101,32,112, + 111,114,116,105,111,110,115,46,32,82,101,116,117,114,110,115, + 32,40,108,111,97,100,101,114,44,32,108,105,115,116,45,111, + 102,45,112,111,114,116,105,111,110,115,41,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,3,114,204,0,0,0,114,141,0,0, + 0,114,179,0,0,0,41,3,114,119,0,0,0,114,140,0, + 0,0,114,188,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,138,0,0,0,134,5,0,0,115, + 8,0,0,0,0,7,10,1,8,1,8,1,122,22,70,105, + 108,101,70,105,110,100,101,114,46,102,105,110,100,95,108,111, + 97,100,101,114,99,6,0,0,0,0,0,0,0,0,0,0, + 0,7,0,0,0,6,0,0,0,67,0,0,0,115,26,0, + 0,0,124,1,124,2,124,3,131,2,125,6,116,0,124,2, + 124,3,124,6,124,4,100,1,141,4,83,0,41,2,78,114, + 178,0,0,0,41,1,114,191,0,0,0,41,7,114,119,0, + 0,0,114,189,0,0,0,114,140,0,0,0,114,44,0,0, + 0,90,4,115,109,115,108,114,203,0,0,0,114,141,0,0, 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 218,14,95,102,105,120,95,117,112,95,109,111,100,117,108,101, - 32,6,0,0,115,34,0,0,0,0,2,10,1,10,1,4, - 1,4,1,8,1,8,1,12,2,10,1,4,1,14,1,2, - 1,8,1,8,1,8,1,12,1,14,2,114,98,1,0,0, - 99,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,3,0,0,0,67,0,0,0,115,38,0,0,0,116,0, - 116,1,160,2,161,0,102,2,125,0,116,3,116,4,102,2, - 125,1,116,5,116,6,102,2,125,2,124,0,124,1,124,2, - 103,3,83,0,41,1,122,95,82,101,116,117,114,110,115,32, - 97,32,108,105,115,116,32,111,102,32,102,105,108,101,45,98, - 97,115,101,100,32,109,111,100,117,108,101,32,108,111,97,100, - 101,114,115,46,10,10,32,32,32,32,69,97,99,104,32,105, - 116,101,109,32,105,115,32,97,32,116,117,112,108,101,32,40, - 108,111,97,100,101,114,44,32,115,117,102,102,105,120,101,115, - 41,46,10,32,32,32,32,41,7,114,252,0,0,0,114,163, - 0,0,0,218,18,101,120,116,101,110,115,105,111,110,95,115, - 117,102,102,105,120,101,115,114,9,1,0,0,114,102,0,0, - 0,114,15,1,0,0,114,89,0,0,0,41,3,90,10,101, - 120,116,101,110,115,105,111,110,115,90,6,115,111,117,114,99, - 101,90,8,98,121,116,101,99,111,100,101,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,184,0,0,0,55, - 6,0,0,115,8,0,0,0,0,5,12,1,8,1,8,1, - 114,184,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,12,0,0,0,9,0,0,0,67,0,0,0,115,178, - 1,0,0,124,0,97,0,116,0,106,1,97,1,116,0,106, - 2,97,2,116,1,106,3,116,4,25,0,125,1,100,1,68, - 0,93,48,125,2,124,2,116,1,106,3,107,7,114,56,116, - 0,160,5,124,2,161,1,125,3,110,10,116,1,106,3,124, - 2,25,0,125,3,116,6,124,1,124,2,124,3,131,3,1, - 0,113,30,100,2,100,3,103,1,102,2,100,4,100,5,100, - 3,103,2,102,2,102,2,125,4,124,4,68,0,93,110,92, - 2,125,5,125,6,116,7,100,6,100,7,132,0,124,6,68, - 0,131,1,131,1,115,136,116,8,130,1,124,6,100,8,25, - 0,125,7,124,5,116,1,106,3,107,6,114,170,116,1,106, - 3,124,5,25,0,125,8,1,0,113,226,113,106,122,20,116, - 0,160,5,124,5,161,1,125,8,87,0,1,0,113,226,87, - 0,113,106,4,0,116,9,107,10,114,214,1,0,1,0,1, - 0,89,0,113,106,89,0,113,106,88,0,113,106,116,9,100, - 9,131,1,130,1,116,6,124,1,100,10,124,8,131,3,1, - 0,116,6,124,1,100,11,124,7,131,3,1,0,116,6,124, - 1,100,12,100,13,160,10,124,6,161,1,131,3,1,0,116, - 6,124,1,100,14,100,15,100,16,132,0,124,6,68,0,131, - 1,131,3,1,0,116,0,160,5,100,17,161,1,125,9,116, - 6,124,1,100,17,124,9,131,3,1,0,116,0,160,5,100, - 18,161,1,125,10,116,6,124,1,100,18,124,10,131,3,1, - 0,124,5,100,4,107,2,144,1,114,110,116,0,160,5,100, - 19,161,1,125,11,116,6,124,1,100,20,124,11,131,3,1, - 0,116,6,124,1,100,21,116,11,131,0,131,3,1,0,116, - 12,160,13,116,2,160,14,161,0,161,1,1,0,124,5,100, - 4,107,2,144,1,114,174,116,15,160,16,100,22,161,1,1, - 0,100,23,116,12,107,6,144,1,114,174,100,24,116,17,95, - 18,100,25,83,0,41,26,122,205,83,101,116,117,112,32,116, + 114,59,1,0,0,146,5,0,0,115,8,0,0,0,0,1, + 10,1,8,1,2,255,122,20,70,105,108,101,70,105,110,100, + 101,114,46,95,103,101,116,95,115,112,101,99,78,99,3,0, + 0,0,0,0,0,0,0,0,0,0,14,0,0,0,8,0, + 0,0,67,0,0,0,115,98,1,0,0,100,1,125,3,124, + 1,160,0,100,2,161,1,100,3,25,0,125,4,122,24,116, + 1,124,0,106,2,112,34,116,3,160,4,161,0,131,1,106, + 5,125,5,87,0,110,24,4,0,116,6,107,10,114,66,1, + 0,1,0,1,0,100,4,125,5,89,0,110,2,88,0,124, + 5,124,0,106,7,107,3,114,92,124,0,160,8,161,0,1, + 0,124,5,124,0,95,7,116,9,131,0,114,114,124,0,106, + 10,125,6,124,4,160,11,161,0,125,7,110,10,124,0,106, + 12,125,6,124,4,125,7,124,7,124,6,107,6,114,218,116, + 13,124,0,106,2,124,4,131,2,125,8,124,0,106,14,68, + 0,93,58,92,2,125,9,125,10,100,5,124,9,23,0,125, + 11,116,13,124,8,124,11,131,2,125,12,116,15,124,12,131, + 1,114,150,124,0,160,16,124,10,124,1,124,12,124,8,103, + 1,124,2,161,5,2,0,1,0,83,0,113,150,116,17,124, + 8,131,1,125,3,124,0,106,14,68,0,93,82,92,2,125, + 9,125,10,116,13,124,0,106,2,124,4,124,9,23,0,131, + 2,125,12,116,18,106,19,100,6,124,12,100,3,100,7,141, + 3,1,0,124,7,124,9,23,0,124,6,107,6,114,224,116, + 15,124,12,131,1,114,224,124,0,160,16,124,10,124,1,124, + 12,100,8,124,2,161,5,2,0,1,0,83,0,113,224,124, + 3,144,1,114,94,116,18,160,19,100,9,124,8,161,2,1, + 0,116,18,160,20,124,1,100,8,161,2,125,13,124,8,103, + 1,124,13,95,21,124,13,83,0,100,8,83,0,41,10,122, + 111,84,114,121,32,116,111,32,102,105,110,100,32,97,32,115, + 112,101,99,32,102,111,114,32,116,104,101,32,115,112,101,99, + 105,102,105,101,100,32,109,111,100,117,108,101,46,10,10,32, + 32,32,32,32,32,32,32,82,101,116,117,114,110,115,32,116, + 104,101,32,109,97,116,99,104,105,110,103,32,115,112,101,99, + 44,32,111,114,32,78,111,110,101,32,105,102,32,110,111,116, + 32,102,111,117,110,100,46,10,32,32,32,32,32,32,32,32, + 70,114,71,0,0,0,114,28,0,0,0,114,105,0,0,0, + 114,210,0,0,0,122,9,116,114,121,105,110,103,32,123,125, + 41,1,90,9,118,101,114,98,111,115,105,116,121,78,122,25, + 112,111,115,115,105,98,108,101,32,110,97,109,101,115,112,97, + 99,101,32,102,111,114,32,123,125,41,22,114,41,0,0,0, + 114,49,0,0,0,114,44,0,0,0,114,2,0,0,0,114, + 55,0,0,0,114,11,1,0,0,114,50,0,0,0,114,65, + 1,0,0,218,11,95,102,105,108,108,95,99,97,99,104,101, + 114,7,0,0,0,114,68,1,0,0,114,106,0,0,0,114, + 67,1,0,0,114,38,0,0,0,114,64,1,0,0,114,54, + 0,0,0,114,59,1,0,0,114,56,0,0,0,114,135,0, + 0,0,114,150,0,0,0,114,184,0,0,0,114,179,0,0, + 0,41,14,114,119,0,0,0,114,140,0,0,0,114,203,0, + 0,0,90,12,105,115,95,110,97,109,101,115,112,97,99,101, + 90,11,116,97,105,108,95,109,111,100,117,108,101,114,170,0, + 0,0,90,5,99,97,99,104,101,90,12,99,97,99,104,101, + 95,109,111,100,117,108,101,90,9,98,97,115,101,95,112,97, + 116,104,114,18,1,0,0,114,189,0,0,0,90,13,105,110, + 105,116,95,102,105,108,101,110,97,109,101,90,9,102,117,108, + 108,95,112,97,116,104,114,188,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,204,0,0,0,151, + 5,0,0,115,74,0,0,0,0,5,4,1,14,1,2,1, + 24,1,14,1,10,1,10,1,8,1,6,2,6,1,6,1, + 10,2,6,1,4,2,8,1,12,1,14,1,8,1,10,1, + 8,1,26,4,8,2,14,1,16,1,16,1,12,1,8,1, + 10,1,2,0,2,255,10,2,6,1,12,1,12,1,8,1, + 4,1,122,20,70,105,108,101,70,105,110,100,101,114,46,102, + 105,110,100,95,115,112,101,99,99,1,0,0,0,0,0,0, + 0,0,0,0,0,9,0,0,0,10,0,0,0,67,0,0, + 0,115,190,0,0,0,124,0,106,0,125,1,122,22,116,1, + 160,2,124,1,112,22,116,1,160,3,161,0,161,1,125,2, + 87,0,110,30,4,0,116,4,116,5,116,6,102,3,107,10, + 114,58,1,0,1,0,1,0,103,0,125,2,89,0,110,2, + 88,0,116,7,106,8,160,9,100,1,161,1,115,84,116,10, + 124,2,131,1,124,0,95,11,110,74,116,10,131,0,125,3, + 124,2,68,0,93,56,125,4,124,4,160,12,100,2,161,1, + 92,3,125,5,125,6,125,7,124,6,114,136,100,3,160,13, + 124,5,124,7,160,14,161,0,161,2,125,8,110,4,124,5, + 125,8,124,3,160,15,124,8,161,1,1,0,113,94,124,3, + 124,0,95,11,116,7,106,8,160,9,116,16,161,1,114,186, + 100,4,100,5,132,0,124,2,68,0,131,1,124,0,95,17, + 100,6,83,0,41,7,122,68,70,105,108,108,32,116,104,101, + 32,99,97,99,104,101,32,111,102,32,112,111,116,101,110,116, + 105,97,108,32,109,111,100,117,108,101,115,32,97,110,100,32, + 112,97,99,107,97,103,101,115,32,102,111,114,32,116,104,105, + 115,32,100,105,114,101,99,116,111,114,121,46,114,0,0,0, + 0,114,71,0,0,0,114,61,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,4,0,0,0, + 83,0,0,0,115,20,0,0,0,104,0,124,0,93,12,125, + 1,124,1,160,0,161,0,146,2,113,4,83,0,114,3,0, + 0,0,41,1,114,106,0,0,0,41,2,114,32,0,0,0, + 90,2,102,110,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,218,9,60,115,101,116,99,111,109,112,62,228,5, + 0,0,115,4,0,0,0,6,0,2,0,122,41,70,105,108, + 101,70,105,110,100,101,114,46,95,102,105,108,108,95,99,97, + 99,104,101,46,60,108,111,99,97,108,115,62,46,60,115,101, + 116,99,111,109,112,62,78,41,18,114,44,0,0,0,114,2, + 0,0,0,114,8,1,0,0,114,55,0,0,0,114,4,1, + 0,0,218,15,80,101,114,109,105,115,115,105,111,110,69,114, + 114,111,114,218,18,78,111,116,65,68,105,114,101,99,116,111, + 114,121,69,114,114,111,114,114,8,0,0,0,114,9,0,0, + 0,114,10,0,0,0,114,66,1,0,0,114,67,1,0,0, + 114,101,0,0,0,114,62,0,0,0,114,106,0,0,0,218, + 3,97,100,100,114,11,0,0,0,114,68,1,0,0,41,9, + 114,119,0,0,0,114,44,0,0,0,114,9,1,0,0,90, + 21,108,111,119,101,114,95,115,117,102,102,105,120,95,99,111, + 110,116,101,110,116,115,114,42,1,0,0,114,117,0,0,0, + 114,30,1,0,0,114,18,1,0,0,90,8,110,101,119,95, + 110,97,109,101,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,114,70,1,0,0,199,5,0,0,115,34,0,0, + 0,0,2,6,1,2,1,22,1,20,3,10,3,12,1,12, + 7,6,1,8,1,16,1,4,1,18,2,4,1,12,1,6, + 1,12,1,122,22,70,105,108,101,70,105,110,100,101,114,46, + 95,102,105,108,108,95,99,97,99,104,101,99,1,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, + 7,0,0,0,115,18,0,0,0,135,0,135,1,102,2,100, + 1,100,2,132,8,125,2,124,2,83,0,41,3,97,20,1, + 0,0,65,32,99,108,97,115,115,32,109,101,116,104,111,100, + 32,119,104,105,99,104,32,114,101,116,117,114,110,115,32,97, + 32,99,108,111,115,117,114,101,32,116,111,32,117,115,101,32, + 111,110,32,115,121,115,46,112,97,116,104,95,104,111,111,107, + 10,32,32,32,32,32,32,32,32,119,104,105,99,104,32,119, + 105,108,108,32,114,101,116,117,114,110,32,97,110,32,105,110, + 115,116,97,110,99,101,32,117,115,105,110,103,32,116,104,101, + 32,115,112,101,99,105,102,105,101,100,32,108,111,97,100,101, + 114,115,32,97,110,100,32,116,104,101,32,112,97,116,104,10, + 32,32,32,32,32,32,32,32,99,97,108,108,101,100,32,111, + 110,32,116,104,101,32,99,108,111,115,117,114,101,46,10,10, + 32,32,32,32,32,32,32,32,73,102,32,116,104,101,32,112, + 97,116,104,32,99,97,108,108,101,100,32,111,110,32,116,104, + 101,32,99,108,111,115,117,114,101,32,105,115,32,110,111,116, + 32,97,32,100,105,114,101,99,116,111,114,121,44,32,73,109, + 112,111,114,116,69,114,114,111,114,32,105,115,10,32,32,32, + 32,32,32,32,32,114,97,105,115,101,100,46,10,10,32,32, + 32,32,32,32,32,32,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,4,0,0,0,19,0,0,0,115, + 34,0,0,0,116,0,124,0,131,1,115,20,116,1,100,1, + 124,0,100,2,141,2,130,1,136,0,124,0,102,1,136,1, + 158,2,142,0,83,0,41,3,122,45,80,97,116,104,32,104, + 111,111,107,32,102,111,114,32,105,109,112,111,114,116,108,105, + 98,46,109,97,99,104,105,110,101,114,121,46,70,105,108,101, + 70,105,110,100,101,114,46,122,30,111,110,108,121,32,100,105, + 114,101,99,116,111,114,105,101,115,32,97,114,101,32,115,117, + 112,112,111,114,116,101,100,114,48,0,0,0,41,2,114,56, + 0,0,0,114,118,0,0,0,114,48,0,0,0,169,2,114, + 194,0,0,0,114,69,1,0,0,114,3,0,0,0,114,6, + 0,0,0,218,24,112,97,116,104,95,104,111,111,107,95,102, + 111,114,95,70,105,108,101,70,105,110,100,101,114,240,5,0, + 0,115,6,0,0,0,0,2,8,1,12,1,122,54,70,105, + 108,101,70,105,110,100,101,114,46,112,97,116,104,95,104,111, + 111,107,46,60,108,111,99,97,108,115,62,46,112,97,116,104, + 95,104,111,111,107,95,102,111,114,95,70,105,108,101,70,105, + 110,100,101,114,114,3,0,0,0,41,3,114,194,0,0,0, + 114,69,1,0,0,114,76,1,0,0,114,3,0,0,0,114, + 75,1,0,0,114,6,0,0,0,218,9,112,97,116,104,95, + 104,111,111,107,230,5,0,0,115,4,0,0,0,0,10,14, + 6,122,20,70,105,108,101,70,105,110,100,101,114,46,112,97, + 116,104,95,104,111,111,107,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,12,0,0,0,100,1,160,0,124,0,106,1,161,1,83, + 0,41,2,78,122,16,70,105,108,101,70,105,110,100,101,114, + 40,123,33,114,125,41,41,2,114,62,0,0,0,114,44,0, + 0,0,114,247,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,40,1,0,0,248,5,0,0,115, + 2,0,0,0,0,1,122,19,70,105,108,101,70,105,110,100, + 101,114,46,95,95,114,101,112,114,95,95,41,1,78,41,15, + 114,126,0,0,0,114,125,0,0,0,114,127,0,0,0,114, + 128,0,0,0,114,210,0,0,0,114,47,1,0,0,114,144, + 0,0,0,114,207,0,0,0,114,138,0,0,0,114,59,1, + 0,0,114,204,0,0,0,114,70,1,0,0,114,208,0,0, + 0,114,77,1,0,0,114,40,1,0,0,114,3,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 62,1,0,0,105,5,0,0,115,22,0,0,0,8,2,4, + 7,8,14,8,4,4,2,8,12,8,5,10,48,8,31,2, + 1,10,17,114,62,1,0,0,99,4,0,0,0,0,0,0, + 0,0,0,0,0,6,0,0,0,8,0,0,0,67,0,0, + 0,115,146,0,0,0,124,0,160,0,100,1,161,1,125,4, + 124,0,160,0,100,2,161,1,125,5,124,4,115,66,124,5, + 114,36,124,5,106,1,125,4,110,30,124,2,124,3,107,2, + 114,56,116,2,124,1,124,2,131,2,125,4,110,10,116,3, + 124,1,124,2,131,2,125,4,124,5,115,84,116,4,124,1, + 124,2,124,4,100,3,141,3,125,5,122,36,124,5,124,0, + 100,2,60,0,124,4,124,0,100,1,60,0,124,2,124,0, + 100,4,60,0,124,3,124,0,100,5,60,0,87,0,110,20, + 4,0,116,5,107,10,114,140,1,0,1,0,1,0,89,0, + 110,2,88,0,100,0,83,0,41,6,78,218,10,95,95,108, + 111,97,100,101,114,95,95,218,8,95,95,115,112,101,99,95, + 95,114,63,1,0,0,90,8,95,95,102,105,108,101,95,95, + 90,10,95,95,99,97,99,104,101,100,95,95,41,6,218,3, + 103,101,116,114,141,0,0,0,114,16,1,0,0,114,10,1, + 0,0,114,191,0,0,0,218,9,69,120,99,101,112,116,105, + 111,110,41,6,90,2,110,115,114,117,0,0,0,90,8,112, + 97,116,104,110,97,109,101,90,9,99,112,97,116,104,110,97, + 109,101,114,141,0,0,0,114,188,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,14,95,102,105, + 120,95,117,112,95,109,111,100,117,108,101,254,5,0,0,115, + 34,0,0,0,0,2,10,1,10,1,4,1,4,1,8,1, + 8,1,12,2,10,1,4,1,14,1,2,1,8,1,8,1, + 8,1,12,1,14,2,114,82,1,0,0,99,0,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, + 67,0,0,0,115,38,0,0,0,116,0,116,1,160,2,161, + 0,102,2,125,0,116,3,116,4,102,2,125,1,116,5,116, + 6,102,2,125,2,124,0,124,1,124,2,103,3,83,0,41, + 1,122,95,82,101,116,117,114,110,115,32,97,32,108,105,115, + 116,32,111,102,32,102,105,108,101,45,98,97,115,101,100,32, + 109,111,100,117,108,101,32,108,111,97,100,101,114,115,46,10, + 10,32,32,32,32,69,97,99,104,32,105,116,101,109,32,105, + 115,32,97,32,116,117,112,108,101,32,40,108,111,97,100,101, + 114,44,32,115,117,102,102,105,120,101,115,41,46,10,32,32, + 32,32,41,7,114,253,0,0,0,114,164,0,0,0,218,18, + 101,120,116,101,110,115,105,111,110,95,115,117,102,102,105,120, + 101,115,114,10,1,0,0,114,102,0,0,0,114,16,1,0, + 0,114,89,0,0,0,41,3,90,10,101,120,116,101,110,115, + 105,111,110,115,90,6,115,111,117,114,99,101,90,8,98,121, + 116,101,99,111,100,101,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,185,0,0,0,21,6,0,0,115,8, + 0,0,0,0,5,12,1,8,1,8,1,114,185,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,12,0,0, + 0,9,0,0,0,67,0,0,0,115,178,1,0,0,124,0, + 97,0,116,0,106,1,97,1,116,0,106,2,97,2,116,1, + 106,3,116,4,25,0,125,1,100,1,68,0,93,48,125,2, + 124,2,116,1,106,3,107,7,114,56,116,0,160,5,124,2, + 161,1,125,3,110,10,116,1,106,3,124,2,25,0,125,3, + 116,6,124,1,124,2,124,3,131,3,1,0,113,30,100,2, + 100,3,103,1,102,2,100,4,100,5,100,3,103,2,102,2, + 102,2,125,4,124,4,68,0,93,110,92,2,125,5,125,6, + 116,7,100,6,100,7,132,0,124,6,68,0,131,1,131,1, + 115,136,116,8,130,1,124,6,100,8,25,0,125,7,124,5, + 116,1,106,3,107,6,114,170,116,1,106,3,124,5,25,0, + 125,8,1,0,113,226,113,106,122,20,116,0,160,5,124,5, + 161,1,125,8,87,0,1,0,113,226,87,0,113,106,4,0, + 116,9,107,10,114,214,1,0,1,0,1,0,89,0,113,106, + 89,0,113,106,88,0,113,106,116,9,100,9,131,1,130,1, + 116,6,124,1,100,10,124,8,131,3,1,0,116,6,124,1, + 100,11,124,7,131,3,1,0,116,6,124,1,100,12,100,13, + 160,10,124,6,161,1,131,3,1,0,116,6,124,1,100,14, + 100,15,100,16,132,0,124,6,68,0,131,1,131,3,1,0, + 116,0,160,5,100,17,161,1,125,9,116,6,124,1,100,17, + 124,9,131,3,1,0,116,0,160,5,100,18,161,1,125,10, + 116,6,124,1,100,18,124,10,131,3,1,0,124,5,100,4, + 107,2,144,1,114,110,116,0,160,5,100,19,161,1,125,11, + 116,6,124,1,100,20,124,11,131,3,1,0,116,6,124,1, + 100,21,116,11,131,0,131,3,1,0,116,12,160,13,116,2, + 160,14,161,0,161,1,1,0,124,5,100,4,107,2,144,1, + 114,174,116,15,160,16,100,22,161,1,1,0,100,23,116,12, + 107,6,144,1,114,174,100,24,116,17,95,18,100,25,83,0, + 41,26,122,205,83,101,116,117,112,32,116,104,101,32,112,97, + 116,104,45,98,97,115,101,100,32,105,109,112,111,114,116,101, + 114,115,32,102,111,114,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,10,32,32,32,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,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,79,116,104, + 101,114,32,99,111,109,112,111,110,101,110,116,115,32,97,114, + 101,32,101,120,116,114,97,99,116,101,100,32,102,114,111,109, + 32,116,104,101,32,99,111,114,101,32,98,111,111,116,115,116, + 114,97,112,32,109,111,100,117,108,101,46,10,10,32,32,32, + 32,41,4,114,64,0,0,0,114,75,0,0,0,218,8,98, + 117,105,108,116,105,110,115,114,161,0,0,0,90,5,112,111, + 115,105,120,250,1,47,90,2,110,116,250,1,92,99,1,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0, + 0,0,115,0,0,0,115,26,0,0,0,124,0,93,18,125, + 1,116,0,124,1,131,1,100,0,107,2,86,0,1,0,113, + 2,100,1,83,0,41,2,114,39,0,0,0,78,41,1,114, + 22,0,0,0,41,2,114,32,0,0,0,114,95,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 20,1,0,0,57,6,0,0,115,4,0,0,0,4,0,2, + 0,122,25,95,115,101,116,117,112,46,60,108,111,99,97,108, + 115,62,46,60,103,101,110,101,120,112,114,62,114,73,0,0, + 0,122,30,105,109,112,111,114,116,108,105,98,32,114,101,113, + 117,105,114,101,115,32,112,111,115,105,120,32,111,114,32,110, + 116,114,2,0,0,0,114,35,0,0,0,114,31,0,0,0, + 114,40,0,0,0,114,58,0,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,83, + 0,0,0,115,22,0,0,0,104,0,124,0,93,14,125,1, + 100,0,124,1,155,0,157,2,146,2,113,4,83,0,41,1, + 114,74,0,0,0,114,3,0,0,0,41,2,114,32,0,0, + 0,218,1,115,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,114,71,1,0,0,73,6,0,0,115,4,0,0, + 0,6,0,2,0,122,25,95,115,101,116,117,112,46,60,108, + 111,99,97,108,115,62,46,60,115,101,116,99,111,109,112,62, + 90,7,95,116,104,114,101,97,100,90,8,95,119,101,97,107, + 114,101,102,90,6,119,105,110,114,101,103,114,193,0,0,0, + 114,7,0,0,0,122,4,46,112,121,119,122,6,95,100,46, + 112,121,100,84,78,41,19,114,135,0,0,0,114,8,0,0, + 0,114,164,0,0,0,114,32,1,0,0,114,126,0,0,0, + 90,18,95,98,117,105,108,116,105,110,95,102,114,111,109,95, + 110,97,109,101,114,130,0,0,0,218,3,97,108,108,114,23, + 0,0,0,114,118,0,0,0,114,36,0,0,0,114,13,0, + 0,0,114,22,1,0,0,114,168,0,0,0,114,83,1,0, + 0,114,102,0,0,0,114,187,0,0,0,114,192,0,0,0, + 114,196,0,0,0,41,12,218,17,95,98,111,111,116,115,116, + 114,97,112,95,109,111,100,117,108,101,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,90,10,111,115,95,100,101,116,97,105,108, + 115,90,10,98,117,105,108,116,105,110,95,111,115,114,31,0, + 0,0,114,35,0,0,0,90,9,111,115,95,109,111,100,117, + 108,101,90,13,116,104,114,101,97,100,95,109,111,100,117,108, + 101,90,14,119,101,97,107,114,101,102,95,109,111,100,117,108, + 101,90,13,119,105,110,114,101,103,95,109,111,100,117,108,101, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 6,95,115,101,116,117,112,32,6,0,0,115,78,0,0,0, + 0,8,4,1,6,1,6,3,10,1,8,1,10,1,12,2, + 10,1,14,3,22,1,12,2,22,1,8,1,10,1,10,1, + 6,2,2,1,10,1,10,1,14,1,12,2,8,1,12,1, + 12,1,18,1,22,3,10,1,12,3,10,1,12,3,10,1, + 10,1,12,3,14,1,14,1,10,1,10,1,10,1,114,90, + 1,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,4,0,0,0,67,0,0,0,115,50,0,0, + 0,116,0,124,0,131,1,1,0,116,1,131,0,125,1,116, + 2,106,3,160,4,116,5,106,6,124,1,142,0,103,1,161, + 1,1,0,116,2,106,7,160,8,116,9,161,1,1,0,100, + 1,83,0,41,2,122,41,73,110,115,116,97,108,108,32,116, 104,101,32,112,97,116,104,45,98,97,115,101,100,32,105,109, - 112,111,114,116,101,114,115,32,102,111,114,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,10,32,32,32,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,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,79,116,104,101,114,32,99,111,109,112,111,110,101,110, - 116,115,32,97,114,101,32,101,120,116,114,97,99,116,101,100, - 32,102,114,111,109,32,116,104,101,32,99,111,114,101,32,98, - 111,111,116,115,116,114,97,112,32,109,111,100,117,108,101,46, - 10,10,32,32,32,32,41,4,114,64,0,0,0,114,75,0, - 0,0,218,8,98,117,105,108,116,105,110,115,114,160,0,0, - 0,90,5,112,111,115,105,120,250,1,47,90,2,110,116,250, - 1,92,99,1,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,3,0,0,0,115,0,0,0,115,26,0,0,0, - 124,0,93,18,125,1,116,0,124,1,131,1,100,0,107,2, - 86,0,1,0,113,2,100,1,83,0,41,2,114,39,0,0, - 0,78,41,1,114,22,0,0,0,41,2,114,32,0,0,0, - 114,95,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,19,1,0,0,91,6,0,0,115,4,0, - 0,0,4,0,2,0,122,25,95,115,101,116,117,112,46,60, - 108,111,99,97,108,115,62,46,60,103,101,110,101,120,112,114, - 62,114,73,0,0,0,122,30,105,109,112,111,114,116,108,105, - 98,32,114,101,113,117,105,114,101,115,32,112,111,115,105,120, - 32,111,114,32,110,116,114,2,0,0,0,114,35,0,0,0, - 114,31,0,0,0,114,40,0,0,0,114,58,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 4,0,0,0,83,0,0,0,115,22,0,0,0,104,0,124, - 0,93,14,125,1,100,0,124,1,155,0,157,2,146,2,113, - 4,83,0,41,1,114,74,0,0,0,114,3,0,0,0,41, - 2,114,32,0,0,0,218,1,115,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,88,1,0,0,107,6,0, - 0,115,4,0,0,0,6,0,2,0,122,25,95,115,101,116, - 117,112,46,60,108,111,99,97,108,115,62,46,60,115,101,116, - 99,111,109,112,62,90,7,95,116,104,114,101,97,100,90,8, - 95,119,101,97,107,114,101,102,90,6,119,105,110,114,101,103, - 114,192,0,0,0,114,7,0,0,0,122,4,46,112,121,119, - 122,6,95,100,46,112,121,100,84,78,41,19,114,134,0,0, - 0,114,8,0,0,0,114,163,0,0,0,114,31,1,0,0, - 114,125,0,0,0,90,18,95,98,117,105,108,116,105,110,95, - 102,114,111,109,95,110,97,109,101,114,129,0,0,0,218,3, - 97,108,108,114,23,0,0,0,114,118,0,0,0,114,36,0, - 0,0,114,13,0,0,0,114,21,1,0,0,114,167,0,0, - 0,114,99,1,0,0,114,102,0,0,0,114,186,0,0,0, - 114,191,0,0,0,114,195,0,0,0,41,12,218,17,95,98, - 111,111,116,115,116,114,97,112,95,109,111,100,117,108,101,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,90,10,111,115,95,100, - 101,116,97,105,108,115,90,10,98,117,105,108,116,105,110,95, - 111,115,114,31,0,0,0,114,35,0,0,0,90,9,111,115, - 95,109,111,100,117,108,101,90,13,116,104,114,101,97,100,95, - 109,111,100,117,108,101,90,14,119,101,97,107,114,101,102,95, - 109,111,100,117,108,101,90,13,119,105,110,114,101,103,95,109, - 111,100,117,108,101,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,6,95,115,101,116,117,112,66,6,0,0, - 115,78,0,0,0,0,8,4,1,6,1,6,3,10,1,8, - 1,10,1,12,2,10,1,14,3,22,1,12,2,22,1,8, - 1,10,1,10,1,6,2,2,1,10,1,10,1,14,1,12, - 2,8,1,12,1,12,1,18,1,22,3,10,1,12,3,10, - 1,12,3,10,1,10,1,12,3,14,1,14,1,10,1,10, - 1,10,1,114,106,1,0,0,99,1,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,4,0,0,0,67,0,0, - 0,115,50,0,0,0,116,0,124,0,131,1,1,0,116,1, - 131,0,125,1,116,2,106,3,160,4,116,5,106,6,124,1, - 142,0,103,1,161,1,1,0,116,2,106,7,160,8,116,9, - 161,1,1,0,100,1,83,0,41,2,122,41,73,110,115,116, - 97,108,108,32,116,104,101,32,112,97,116,104,45,98,97,115, - 101,100,32,105,109,112,111,114,116,32,99,111,109,112,111,110, - 101,110,116,115,46,78,41,10,114,106,1,0,0,114,184,0, - 0,0,114,8,0,0,0,114,51,1,0,0,114,167,0,0, - 0,114,79,1,0,0,114,94,1,0,0,218,9,109,101,116, - 97,95,112,97,116,104,114,186,0,0,0,114,45,1,0,0, - 41,2,114,105,1,0,0,90,17,115,117,112,112,111,114,116, - 101,100,95,108,111,97,100,101,114,115,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,8,95,105,110,115,116, - 97,108,108,131,6,0,0,115,8,0,0,0,0,2,8,1, - 6,1,20,1,114,108,1,0,0,41,63,114,127,0,0,0, - 114,12,0,0,0,90,37,95,67,65,83,69,95,73,78,83, - 69,78,83,73,84,73,86,69,95,80,76,65,84,70,79,82, - 77,83,95,66,89,84,69,83,95,75,69,89,114,11,0,0, - 0,114,13,0,0,0,114,20,0,0,0,114,27,0,0,0, - 114,29,0,0,0,114,38,0,0,0,114,47,0,0,0,114, - 49,0,0,0,114,53,0,0,0,114,54,0,0,0,114,56, - 0,0,0,114,59,0,0,0,114,69,0,0,0,218,4,116, - 121,112,101,218,8,95,95,99,111,100,101,95,95,114,162,0, - 0,0,114,18,0,0,0,114,148,0,0,0,114,17,0,0, - 0,114,24,0,0,0,114,236,0,0,0,114,92,0,0,0, - 114,88,0,0,0,114,102,0,0,0,114,89,0,0,0,90, - 23,68,69,66,85,71,95,66,89,84,69,67,79,68,69,95, - 83,85,70,70,73,88,69,83,90,27,79,80,84,73,77,73, - 90,69,68,95,66,89,84,69,67,79,68,69,95,83,85,70, - 70,73,88,69,83,114,98,0,0,0,114,103,0,0,0,114, - 109,0,0,0,114,113,0,0,0,114,115,0,0,0,114,136, - 0,0,0,114,143,0,0,0,114,152,0,0,0,114,156,0, - 0,0,114,158,0,0,0,114,165,0,0,0,114,170,0,0, - 0,114,171,0,0,0,114,176,0,0,0,218,6,111,98,106, - 101,99,116,114,185,0,0,0,114,190,0,0,0,114,191,0, - 0,0,114,208,0,0,0,114,221,0,0,0,114,239,0,0, - 0,114,9,1,0,0,114,15,1,0,0,114,21,1,0,0, - 114,252,0,0,0,114,22,1,0,0,114,43,1,0,0,114, - 45,1,0,0,114,79,1,0,0,114,98,1,0,0,114,184, - 0,0,0,114,106,1,0,0,114,108,1,0,0,114,3,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,8,60,109,111,100,117,108,101,62,1,0,0,0,115, - 126,0,0,0,4,22,4,1,4,1,2,1,2,255,4,4, - 8,17,8,5,8,5,8,6,8,6,8,12,8,10,8,9, - 8,5,8,7,8,9,12,22,10,127,0,8,16,1,12,2, - 4,1,4,2,6,2,6,2,8,2,18,71,8,40,8,19, - 8,12,8,12,8,28,8,17,8,33,8,28,8,24,16,13, - 14,10,12,11,8,14,6,3,6,1,2,255,12,68,14,64, - 14,29,16,127,0,17,14,72,18,45,18,26,4,3,18,53, - 14,63,14,42,14,127,0,59,14,127,0,22,12,23,8,11, - 8,65, + 112,111,114,116,32,99,111,109,112,111,110,101,110,116,115,46, + 78,41,10,114,90,1,0,0,114,185,0,0,0,114,8,0, + 0,0,114,52,1,0,0,114,168,0,0,0,114,62,1,0, + 0,114,77,1,0,0,218,9,109,101,116,97,95,112,97,116, + 104,114,187,0,0,0,114,46,1,0,0,41,2,114,89,1, + 0,0,90,17,115,117,112,112,111,114,116,101,100,95,108,111, + 97,100,101,114,115,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,218,8,95,105,110,115,116,97,108,108,97,6, + 0,0,115,8,0,0,0,0,2,8,1,6,1,20,1,114, + 92,1,0,0,41,1,114,60,0,0,0,41,1,78,41,3, + 78,78,78,41,2,114,73,0,0,0,114,73,0,0,0,41, + 1,84,41,1,78,41,1,78,41,63,114,128,0,0,0,114, + 12,0,0,0,90,37,95,67,65,83,69,95,73,78,83,69, + 78,83,73,84,73,86,69,95,80,76,65,84,70,79,82,77, + 83,95,66,89,84,69,83,95,75,69,89,114,11,0,0,0, + 114,13,0,0,0,114,20,0,0,0,114,27,0,0,0,114, + 29,0,0,0,114,38,0,0,0,114,47,0,0,0,114,49, + 0,0,0,114,53,0,0,0,114,54,0,0,0,114,56,0, + 0,0,114,59,0,0,0,114,69,0,0,0,218,4,116,121, + 112,101,218,8,95,95,99,111,100,101,95,95,114,163,0,0, + 0,114,18,0,0,0,114,149,0,0,0,114,17,0,0,0, + 114,24,0,0,0,114,237,0,0,0,114,92,0,0,0,114, + 88,0,0,0,114,102,0,0,0,114,89,0,0,0,90,23, + 68,69,66,85,71,95,66,89,84,69,67,79,68,69,95,83, + 85,70,70,73,88,69,83,90,27,79,80,84,73,77,73,90, + 69,68,95,66,89,84,69,67,79,68,69,95,83,85,70,70, + 73,88,69,83,114,98,0,0,0,114,103,0,0,0,114,109, + 0,0,0,114,113,0,0,0,114,115,0,0,0,114,137,0, + 0,0,114,144,0,0,0,114,153,0,0,0,114,157,0,0, + 0,114,159,0,0,0,114,166,0,0,0,114,171,0,0,0, + 114,172,0,0,0,114,177,0,0,0,218,6,111,98,106,101, + 99,116,114,186,0,0,0,114,191,0,0,0,114,192,0,0, + 0,114,209,0,0,0,114,222,0,0,0,114,240,0,0,0, + 114,10,1,0,0,114,16,1,0,0,114,22,1,0,0,114, + 253,0,0,0,114,23,1,0,0,114,44,1,0,0,114,46, + 1,0,0,114,62,1,0,0,114,82,1,0,0,114,185,0, + 0,0,114,90,1,0,0,114,92,1,0,0,114,3,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 218,8,60,109,111,100,117,108,101,62,1,0,0,0,115,126, + 0,0,0,4,22,4,1,4,1,2,1,2,255,4,4,8, + 17,8,5,8,5,8,6,8,6,8,12,8,10,8,9,8, + 5,8,7,8,9,10,22,10,127,0,13,16,1,12,2,4, + 1,4,2,6,2,6,2,8,2,16,71,8,40,8,19,8, + 12,8,12,8,28,8,17,8,33,8,28,8,24,10,13,10, + 10,10,11,8,14,6,3,4,1,2,255,12,68,14,64,14, + 29,16,127,0,17,14,72,18,45,18,26,4,3,18,53,14, + 63,14,42,14,127,0,20,14,127,0,22,10,23,8,11,8, + 65, }; diff --git a/Python/importlib_zipimport.h b/Python/importlib_zipimport.h index cbb3d909a10b7b..6c9c4e8465523d 100644 --- a/Python/importlib_zipimport.h +++ b/Python/importlib_zipimport.h @@ -703,18 +703,18 @@ const unsigned char _Py_M__zipimport[] = { 160,99,0,0,0,0,0,0,0,0,0,0,0,0,1,0, 0,0,8,0,0,0,67,0,0,0,115,108,0,0,0,116, 0,114,22,116,1,160,2,100,1,161,1,1,0,116,3,100, - 2,131,1,130,1,100,3,97,0,122,60,122,16,100,4,100, - 5,108,4,109,5,125,0,1,0,87,0,110,38,4,0,116, + 2,131,1,130,1,100,3,97,0,122,60,122,16,100,5,100, + 6,108,4,109,5,125,0,1,0,87,0,110,38,4,0,116, 6,107,10,114,82,1,0,1,0,1,0,116,1,160,2,100, 1,161,1,1,0,116,3,100,2,131,1,130,1,89,0,110, - 2,88,0,87,0,53,0,100,6,97,0,88,0,116,1,160, + 2,88,0,87,0,53,0,100,4,97,0,88,0,116,1,160, 2,100,7,161,1,1,0,124,0,83,0,41,8,78,122,27, 122,105,112,105,109,112,111,114,116,58,32,122,108,105,98,32, 85,78,65,86,65,73,76,65,66,76,69,250,41,99,97,110, 39,116,32,100,101,99,111,109,112,114,101,115,115,32,100,97, 116,97,59,32,122,108,105,98,32,110,111,116,32,97,118,97, - 105,108,97,98,108,101,84,114,0,0,0,0,169,1,218,10, - 100,101,99,111,109,112,114,101,115,115,70,122,25,122,105,112, + 105,108,97,98,108,101,84,70,114,0,0,0,0,169,1,218, + 10,100,101,99,111,109,112,114,101,115,115,122,25,122,105,112, 105,109,112,111,114,116,58,32,122,108,105,98,32,97,118,97, 105,108,97,98,108,101,41,7,218,15,95,105,109,112,111,114, 116,105,110,103,95,122,108,105,98,114,76,0,0,0,114,77, @@ -783,301 +783,301 @@ const unsigned char _Py_M__zipimport[] = { 0,0,0,218,9,95,101,113,95,109,116,105,109,101,65,2, 0,0,115,2,0,0,0,0,2,114,147,0,0,0,99,5, 0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,8, - 0,0,0,67,0,0,0,115,68,1,0,0,124,3,124,2, + 0,0,0,67,0,0,0,115,60,1,0,0,124,3,124,2, 100,1,156,2,125,5,122,18,116,0,160,1,124,4,124,3, - 124,5,161,3,125,6,87,0,110,26,4,0,116,2,107,10, - 114,54,1,0,1,0,1,0,89,0,100,0,83,0,89,0, - 110,2,88,0,124,6,100,2,64,0,100,3,107,3,125,7, - 124,7,114,190,124,6,100,4,64,0,100,3,107,3,125,8, - 116,3,106,4,100,5,107,3,114,188,124,8,115,108,116,3, - 106,4,100,6,107,2,114,188,116,5,124,0,124,2,131,2, - 125,9,124,9,100,0,107,9,114,188,116,3,160,6,116,0, - 106,7,124,9,161,2,125,10,122,20,116,8,160,9,124,4, - 124,10,124,3,124,5,161,4,1,0,87,0,110,26,4,0, - 116,2,107,10,114,186,1,0,1,0,1,0,89,0,100,0, - 83,0,89,0,110,2,88,0,110,84,116,10,124,0,124,2, - 131,2,92,2,125,11,125,12,124,11,144,1,114,18,116,11, - 116,12,124,4,100,7,100,8,133,2,25,0,131,1,124,11, - 131,2,114,254,116,12,124,4,100,8,100,9,133,2,25,0, - 131,1,124,12,107,3,144,1,114,18,116,13,160,14,100,10, - 124,3,155,2,157,2,161,1,1,0,100,0,83,0,116,15, - 160,16,124,4,100,9,100,0,133,2,25,0,161,1,125,13, - 116,17,124,13,116,18,131,2,144,1,115,64,116,19,100,11, - 124,1,155,2,100,12,157,3,131,1,130,1,124,13,83,0, - 41,13,78,41,2,114,59,0,0,0,114,13,0,0,0,114, - 5,0,0,0,114,0,0,0,0,114,86,0,0,0,90,5, - 110,101,118,101,114,90,6,97,108,119,97,121,115,114,99,0, - 0,0,114,94,0,0,0,114,95,0,0,0,122,22,98,121, - 116,101,99,111,100,101,32,105,115,32,115,116,97,108,101,32, - 102,111,114,32,122,16,99,111,109,112,105,108,101,100,32,109, - 111,100,117,108,101,32,122,21,32,105,115,32,110,111,116,32, - 97,32,99,111,100,101,32,111,98,106,101,99,116,41,20,114, - 21,0,0,0,90,13,95,99,108,97,115,115,105,102,121,95, - 112,121,99,114,75,0,0,0,218,4,95,105,109,112,90,21, - 99,104,101,99,107,95,104,97,115,104,95,98,97,115,101,100, - 95,112,121,99,115,218,15,95,103,101,116,95,112,121,99,95, - 115,111,117,114,99,101,218,11,115,111,117,114,99,101,95,104, - 97,115,104,90,17,95,82,65,87,95,77,65,71,73,67,95, - 78,85,77,66,69,82,90,18,95,98,111,111,115,116,114,97, - 112,95,101,120,116,101,114,110,97,108,90,18,95,118,97,108, - 105,100,97,116,101,95,104,97,115,104,95,112,121,99,218,29, - 95,103,101,116,95,109,116,105,109,101,95,97,110,100,95,115, - 105,122,101,95,111,102,95,115,111,117,114,99,101,114,147,0, - 0,0,114,2,0,0,0,114,76,0,0,0,114,77,0,0, - 0,218,7,109,97,114,115,104,97,108,90,5,108,111,97,100, - 115,114,15,0,0,0,218,10,95,99,111,100,101,95,116,121, - 112,101,218,9,84,121,112,101,69,114,114,111,114,41,14,114, - 32,0,0,0,114,53,0,0,0,114,63,0,0,0,114,38, - 0,0,0,114,126,0,0,0,90,11,101,120,99,95,100,101, - 116,97,105,108,115,114,129,0,0,0,90,10,104,97,115,104, - 95,98,97,115,101,100,90,12,99,104,101,99,107,95,115,111, - 117,114,99,101,90,12,115,111,117,114,99,101,95,98,121,116, - 101,115,114,150,0,0,0,90,12,115,111,117,114,99,101,95, - 109,116,105,109,101,90,11,115,111,117,114,99,101,95,115,105, - 122,101,114,46,0,0,0,114,9,0,0,0,114,9,0,0, - 0,114,10,0,0,0,218,15,95,117,110,109,97,114,115,104, - 97,108,95,99,111,100,101,75,2,0,0,115,88,0,0,0, - 0,2,2,1,2,254,6,5,2,1,18,1,14,1,12,2, - 12,1,4,1,12,1,10,1,2,255,2,1,8,255,2,2, - 10,1,8,1,4,1,4,1,2,254,4,5,2,1,4,1, - 2,0,2,0,2,0,2,255,8,2,14,1,14,3,8,255, - 6,3,6,3,22,1,18,255,4,2,4,1,8,255,4,2, - 4,2,18,1,12,1,16,1,114,155,0,0,0,99,1,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0, - 0,0,67,0,0,0,115,28,0,0,0,124,0,160,0,100, - 1,100,2,161,2,125,0,124,0,160,0,100,3,100,2,161, - 2,125,0,124,0,83,0,41,4,78,115,2,0,0,0,13, - 10,243,1,0,0,0,10,243,1,0,0,0,13,41,1,114, - 19,0,0,0,41,1,218,6,115,111,117,114,99,101,114,9, - 0,0,0,114,9,0,0,0,114,10,0,0,0,218,23,95, - 110,111,114,109,97,108,105,122,101,95,108,105,110,101,95,101, - 110,100,105,110,103,115,126,2,0,0,115,6,0,0,0,0, - 1,12,1,12,1,114,159,0,0,0,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,67, - 0,0,0,115,24,0,0,0,116,0,124,1,131,1,125,1, - 116,1,124,1,124,0,100,1,100,2,100,3,141,4,83,0, - 41,4,78,114,74,0,0,0,84,41,1,90,12,100,111,110, - 116,95,105,110,104,101,114,105,116,41,2,114,159,0,0,0, - 218,7,99,111,109,112,105,108,101,41,2,114,53,0,0,0, - 114,158,0,0,0,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,218,15,95,99,111,109,112,105,108,101,95,115, - 111,117,114,99,101,133,2,0,0,115,4,0,0,0,0,1, - 8,1,114,161,0,0,0,99,2,0,0,0,0,0,0,0, - 0,0,0,0,2,0,0,0,11,0,0,0,67,0,0,0, - 115,68,0,0,0,116,0,160,1,124,0,100,1,63,0,100, - 2,23,0,124,0,100,3,63,0,100,4,64,0,124,0,100, - 5,64,0,124,1,100,6,63,0,124,1,100,3,63,0,100, - 7,64,0,124,1,100,5,64,0,100,8,20,0,100,9,100, - 9,100,9,102,9,161,1,83,0,41,10,78,233,9,0,0, - 0,105,188,7,0,0,233,5,0,0,0,233,15,0,0,0, - 233,31,0,0,0,233,11,0,0,0,233,63,0,0,0,114, - 86,0,0,0,114,14,0,0,0,41,2,114,131,0,0,0, - 90,6,109,107,116,105,109,101,41,2,218,1,100,114,138,0, - 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,218,14,95,112,97,114,115,101,95,100,111,115,116,105,109, - 101,139,2,0,0,115,22,0,0,0,0,1,4,1,10,1, - 10,1,6,1,6,1,10,1,10,1,2,0,2,0,2,249, - 114,169,0,0,0,99,2,0,0,0,0,0,0,0,0,0, - 0,0,6,0,0,0,10,0,0,0,67,0,0,0,115,116, - 0,0,0,122,82,124,1,100,1,100,0,133,2,25,0,100, - 2,107,6,115,22,116,0,130,1,124,1,100,0,100,1,133, - 2,25,0,125,1,124,0,106,1,124,1,25,0,125,2,124, - 2,100,3,25,0,125,3,124,2,100,4,25,0,125,4,124, - 2,100,5,25,0,125,5,116,2,124,4,124,3,131,2,124, - 5,102,2,87,0,83,0,4,0,116,3,116,4,116,5,102, - 3,107,10,114,110,1,0,1,0,1,0,89,0,100,6,83, - 0,88,0,100,0,83,0,41,7,78,114,14,0,0,0,169, - 2,218,1,99,218,1,111,114,163,0,0,0,233,6,0,0, - 0,233,3,0,0,0,41,2,114,0,0,0,0,114,0,0, - 0,0,41,6,218,14,65,115,115,101,114,116,105,111,110,69, - 114,114,111,114,114,28,0,0,0,114,169,0,0,0,114,26, - 0,0,0,218,10,73,110,100,101,120,69,114,114,111,114,114, - 154,0,0,0,41,6,114,32,0,0,0,114,13,0,0,0, - 114,54,0,0,0,114,131,0,0,0,114,132,0,0,0,90, - 17,117,110,99,111,109,112,114,101,115,115,101,100,95,115,105, - 122,101,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,151,0,0,0,152,2,0,0,115,20,0,0,0,0, - 1,2,2,20,1,12,1,10,3,8,1,8,1,8,1,16, - 1,20,1,114,151,0,0,0,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,86,0,0,0,124,1,100,1,100,0,133,2,25,0, - 100,2,107,6,115,20,116,0,130,1,124,1,100,0,100,1, - 133,2,25,0,125,1,122,14,124,0,106,1,124,1,25,0, - 125,2,87,0,110,22,4,0,116,2,107,10,114,68,1,0, - 1,0,1,0,89,0,100,0,83,0,88,0,116,3,124,0, - 106,4,124,2,131,2,83,0,100,0,83,0,41,3,78,114, - 14,0,0,0,114,170,0,0,0,41,5,114,175,0,0,0, - 114,28,0,0,0,114,26,0,0,0,114,52,0,0,0,114, - 29,0,0,0,41,3,114,32,0,0,0,114,13,0,0,0, - 114,54,0,0,0,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,114,149,0,0,0,171,2,0,0,115,14,0, - 0,0,0,2,20,1,12,2,2,1,14,1,14,1,8,2, - 114,149,0,0,0,99,2,0,0,0,0,0,0,0,0,0, - 0,0,11,0,0,0,9,0,0,0,67,0,0,0,115,198, - 0,0,0,116,0,124,0,124,1,131,2,125,2,116,1,68, - 0,93,160,92,3,125,3,125,4,125,5,124,2,124,3,23, - 0,125,6,116,2,106,3,100,1,124,0,106,4,116,5,124, - 6,100,2,100,3,141,5,1,0,122,14,124,0,106,6,124, - 6,25,0,125,7,87,0,110,20,4,0,116,7,107,10,114, - 88,1,0,1,0,1,0,89,0,113,14,88,0,124,7,100, - 4,25,0,125,8,116,8,124,0,106,4,124,7,131,2,125, - 9,124,4,114,132,116,9,124,0,124,8,124,6,124,1,124, - 9,131,5,125,10,110,10,116,10,124,8,124,9,131,2,125, - 10,124,10,100,0,107,8,114,152,113,14,124,7,100,4,25, - 0,125,8,124,10,124,5,124,8,102,3,2,0,1,0,83, - 0,113,14,116,11,100,5,124,1,155,2,157,2,124,1,100, - 6,141,2,130,1,100,0,83,0,41,7,78,122,13,116,114, - 121,105,110,103,32,123,125,123,125,123,125,114,86,0,0,0, - 41,1,90,9,118,101,114,98,111,115,105,116,121,114,0,0, - 0,0,114,57,0,0,0,114,58,0,0,0,41,12,114,36, - 0,0,0,114,89,0,0,0,114,76,0,0,0,114,77,0, - 0,0,114,29,0,0,0,114,20,0,0,0,114,28,0,0, - 0,114,26,0,0,0,114,52,0,0,0,114,155,0,0,0, - 114,161,0,0,0,114,3,0,0,0,41,11,114,32,0,0, - 0,114,38,0,0,0,114,13,0,0,0,114,90,0,0,0, - 114,91,0,0,0,114,47,0,0,0,114,63,0,0,0,114, - 54,0,0,0,114,40,0,0,0,114,126,0,0,0,114,46, - 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, - 0,0,114,44,0,0,0,186,2,0,0,115,36,0,0,0, - 0,1,10,1,14,1,8,1,22,1,2,1,14,1,14,1, - 6,2,8,1,12,1,4,1,18,2,10,1,8,3,2,1, - 8,1,16,2,114,44,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,60,0,0,0,101,0,90,1,100,0,90,2,100, - 1,90,3,100,2,90,4,100,3,100,4,132,0,90,5,100, - 5,100,6,132,0,90,6,100,7,100,8,132,0,90,7,100, - 9,100,10,132,0,90,8,100,11,100,12,132,0,90,9,100, - 13,83,0,41,14,114,80,0,0,0,122,165,80,114,105,118, - 97,116,101,32,99,108,97,115,115,32,117,115,101,100,32,116, - 111,32,115,117,112,112,111,114,116,32,90,105,112,73,109,112, - 111,114,116,46,103,101,116,95,114,101,115,111,117,114,99,101, - 95,114,101,97,100,101,114,40,41,46,10,10,32,32,32,32, - 84,104,105,115,32,99,108,97,115,115,32,105,115,32,97,108, - 108,111,119,101,100,32,116,111,32,114,101,102,101,114,101,110, - 99,101,32,97,108,108,32,116,104,101,32,105,110,110,97,114, - 100,115,32,97,110,100,32,112,114,105,118,97,116,101,32,112, - 97,114,116,115,32,111,102,10,32,32,32,32,116,104,101,32, - 122,105,112,105,109,112,111,114,116,101,114,46,10,32,32,32, - 32,70,99,3,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0, - 124,1,124,0,95,0,124,2,124,0,95,1,100,0,83,0, - 114,88,0,0,0,41,2,114,4,0,0,0,114,38,0,0, - 0,41,3,114,32,0,0,0,114,4,0,0,0,114,38,0, - 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,34,0,0,0,220,2,0,0,115,4,0,0,0,0, - 1,6,1,122,33,95,90,105,112,73,109,112,111,114,116,82, - 101,115,111,117,114,99,101,82,101,97,100,101,114,46,95,95, - 105,110,105,116,95,95,99,2,0,0,0,0,0,0,0,0, - 0,0,0,5,0,0,0,8,0,0,0,67,0,0,0,115, - 92,0,0,0,124,0,106,0,160,1,100,1,100,2,161,2, - 125,2,124,2,155,0,100,2,124,1,155,0,157,3,125,3, - 100,3,100,4,108,2,109,3,125,4,1,0,122,18,124,4, - 124,0,106,4,160,5,124,3,161,1,131,1,87,0,83,0, - 4,0,116,6,107,10,114,86,1,0,1,0,1,0,116,7, - 124,3,131,1,130,1,89,0,110,2,88,0,100,0,83,0, - 41,5,78,114,85,0,0,0,114,109,0,0,0,114,0,0, - 0,0,41,1,218,7,66,121,116,101,115,73,79,41,8,114, - 38,0,0,0,114,19,0,0,0,90,2,105,111,114,177,0, - 0,0,114,4,0,0,0,114,55,0,0,0,114,22,0,0, - 0,218,17,70,105,108,101,78,111,116,70,111,117,110,100,69, - 114,114,111,114,41,5,114,32,0,0,0,218,8,114,101,115, - 111,117,114,99,101,218,16,102,117,108,108,110,97,109,101,95, - 97,115,95,112,97,116,104,114,13,0,0,0,114,177,0,0, - 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, - 218,13,111,112,101,110,95,114,101,115,111,117,114,99,101,224, - 2,0,0,115,14,0,0,0,0,1,14,1,14,1,12,1, - 2,1,18,1,14,1,122,38,95,90,105,112,73,109,112,111, - 114,116,82,101,115,111,117,114,99,101,82,101,97,100,101,114, - 46,111,112,101,110,95,114,101,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,8,0,0,0,116,0,130,1, - 100,0,83,0,114,88,0,0,0,41,1,114,178,0,0,0, - 41,2,114,32,0,0,0,114,179,0,0,0,114,9,0,0, - 0,114,9,0,0,0,114,10,0,0,0,218,13,114,101,115, - 111,117,114,99,101,95,112,97,116,104,233,2,0,0,115,2, - 0,0,0,0,4,122,38,95,90,105,112,73,109,112,111,114, - 116,82,101,115,111,117,114,99,101,82,101,97,100,101,114,46, - 114,101,115,111,117,114,99,101,95,112,97,116,104,99,2,0, - 0,0,0,0,0,0,0,0,0,0,4,0,0,0,8,0, - 0,0,67,0,0,0,115,72,0,0,0,124,0,106,0,160, - 1,100,1,100,2,161,2,125,2,124,2,155,0,100,2,124, - 1,155,0,157,3,125,3,122,16,124,0,106,2,160,3,124, - 3,161,1,1,0,87,0,110,22,4,0,116,4,107,10,114, - 66,1,0,1,0,1,0,89,0,100,3,83,0,88,0,100, - 4,83,0,41,5,78,114,85,0,0,0,114,109,0,0,0, - 70,84,41,5,114,38,0,0,0,114,19,0,0,0,114,4, - 0,0,0,114,55,0,0,0,114,22,0,0,0,41,4,114, - 32,0,0,0,114,59,0,0,0,114,180,0,0,0,114,13, - 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, - 0,0,218,11,105,115,95,114,101,115,111,117,114,99,101,239, - 2,0,0,115,14,0,0,0,0,3,14,1,14,1,2,1, - 16,1,14,1,8,1,122,36,95,90,105,112,73,109,112,111, - 114,116,82,101,115,111,117,114,99,101,82,101,97,100,101,114, - 46,105,115,95,114,101,115,111,117,114,99,101,99,1,0,0, - 0,0,0,0,0,0,0,0,0,9,0,0,0,9,0,0, - 0,99,0,0,0,115,186,0,0,0,100,1,100,2,108,0, - 109,1,125,1,1,0,124,1,124,0,106,2,160,3,124,0, - 106,4,161,1,131,1,125,2,124,2,160,5,124,0,106,2, - 106,6,161,1,125,3,124,3,106,7,100,3,107,2,115,58, - 116,8,130,1,124,3,106,9,125,4,116,10,131,0,125,5, - 124,0,106,2,106,11,68,0,93,102,125,6,122,18,124,1, - 124,6,131,1,160,5,124,4,161,1,125,7,87,0,110,24, - 4,0,116,12,107,10,114,124,1,0,1,0,1,0,89,0, - 113,78,89,0,110,2,88,0,124,7,106,9,106,7,125,8, - 116,13,124,8,131,1,100,1,107,2,114,156,124,7,106,7, - 86,0,1,0,113,78,124,8,124,5,107,7,114,78,124,5, - 160,14,124,8,161,1,1,0,124,8,86,0,1,0,113,78, - 100,0,83,0,41,4,78,114,0,0,0,0,41,1,218,4, - 80,97,116,104,114,60,0,0,0,41,15,90,7,112,97,116, - 104,108,105,98,114,184,0,0,0,114,4,0,0,0,114,56, - 0,0,0,114,38,0,0,0,90,11,114,101,108,97,116,105, - 118,101,95,116,111,114,29,0,0,0,114,59,0,0,0,114, - 175,0,0,0,90,6,112,97,114,101,110,116,218,3,115,101, - 116,114,28,0,0,0,114,23,0,0,0,114,51,0,0,0, - 218,3,97,100,100,41,9,114,32,0,0,0,114,184,0,0, - 0,90,13,102,117,108,108,110,97,109,101,95,112,97,116,104, - 90,13,114,101,108,97,116,105,118,101,95,112,97,116,104,90, - 12,112,97,99,107,97,103,101,95,112,97,116,104,90,12,115, - 117,98,100,105,114,115,95,115,101,101,110,218,8,102,105,108, - 101,110,97,109,101,90,8,114,101,108,97,116,105,118,101,90, - 11,112,97,114,101,110,116,95,110,97,109,101,114,9,0,0, - 0,114,9,0,0,0,114,10,0,0,0,218,8,99,111,110, - 116,101,110,116,115,250,2,0,0,115,34,0,0,0,0,8, - 12,1,18,1,14,3,14,1,6,1,6,1,12,1,2,1, - 18,1,14,1,10,5,8,1,12,1,10,1,8,1,10,1, - 122,33,95,90,105,112,73,109,112,111,114,116,82,101,115,111, - 117,114,99,101,82,101,97,100,101,114,46,99,111,110,116,101, - 110,116,115,78,41,10,114,6,0,0,0,114,7,0,0,0, - 114,8,0,0,0,114,84,0,0,0,114,81,0,0,0,114, - 34,0,0,0,114,181,0,0,0,114,182,0,0,0,114,183, - 0,0,0,114,188,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,114,80,0,0, - 0,212,2,0,0,115,14,0,0,0,8,1,4,5,4,2, - 8,4,8,9,8,6,8,11,114,80,0,0,0,41,45,114, - 84,0,0,0,90,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,21,0,0,0,114,1,0,0,0,114,2,0,0,0,90, - 17,95,102,114,111,122,101,110,95,105,109,112,111,114,116,108, - 105,98,114,76,0,0,0,114,148,0,0,0,114,110,0,0, - 0,114,152,0,0,0,114,67,0,0,0,114,131,0,0,0, - 90,7,95,95,97,108,108,95,95,114,20,0,0,0,90,15, - 112,97,116,104,95,115,101,112,97,114,97,116,111,114,115,114, - 18,0,0,0,114,75,0,0,0,114,3,0,0,0,114,25, - 0,0,0,218,4,116,121,112,101,114,70,0,0,0,114,113, - 0,0,0,114,115,0,0,0,114,117,0,0,0,114,4,0, - 0,0,114,89,0,0,0,114,36,0,0,0,114,37,0,0, - 0,114,35,0,0,0,114,27,0,0,0,114,122,0,0,0, - 114,142,0,0,0,114,144,0,0,0,114,52,0,0,0,114, - 147,0,0,0,114,155,0,0,0,218,8,95,95,99,111,100, - 101,95,95,114,153,0,0,0,114,159,0,0,0,114,161,0, - 0,0,114,169,0,0,0,114,151,0,0,0,114,149,0,0, - 0,114,44,0,0,0,114,80,0,0,0,114,9,0,0,0, - 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,218, - 8,60,109,111,100,117,108,101,62,1,0,0,0,115,88,0, - 0,0,4,16,8,1,16,1,8,1,8,1,8,1,8,1, - 8,1,8,2,8,3,6,1,14,3,16,4,4,2,8,2, - 4,1,4,1,4,2,14,127,0,127,0,1,12,1,12,1, - 2,1,2,252,4,9,8,4,8,9,8,31,8,126,2,254, - 2,29,4,5,8,21,8,46,8,10,8,46,10,5,8,7, - 8,6,8,13,8,19,8,15,8,26, + 124,5,161,3,125,6,87,0,110,22,4,0,116,2,107,10, + 114,50,1,0,1,0,1,0,89,0,100,0,83,0,88,0, + 124,6,100,2,64,0,100,3,107,3,125,7,124,7,114,182, + 124,6,100,4,64,0,100,3,107,3,125,8,116,3,106,4, + 100,5,107,3,114,180,124,8,115,104,116,3,106,4,100,6, + 107,2,114,180,116,5,124,0,124,2,131,2,125,9,124,9, + 100,0,107,9,114,180,116,3,160,6,116,0,106,7,124,9, + 161,2,125,10,122,20,116,8,160,9,124,4,124,10,124,3, + 124,5,161,4,1,0,87,0,110,22,4,0,116,2,107,10, + 114,178,1,0,1,0,1,0,89,0,100,0,83,0,88,0, + 110,84,116,10,124,0,124,2,131,2,92,2,125,11,125,12, + 124,11,144,1,114,10,116,11,116,12,124,4,100,7,100,8, + 133,2,25,0,131,1,124,11,131,2,114,246,116,12,124,4, + 100,8,100,9,133,2,25,0,131,1,124,12,107,3,144,1, + 114,10,116,13,160,14,100,10,124,3,155,2,157,2,161,1, + 1,0,100,0,83,0,116,15,160,16,124,4,100,9,100,0, + 133,2,25,0,161,1,125,13,116,17,124,13,116,18,131,2, + 144,1,115,56,116,19,100,11,124,1,155,2,100,12,157,3, + 131,1,130,1,124,13,83,0,41,13,78,41,2,114,59,0, + 0,0,114,13,0,0,0,114,5,0,0,0,114,0,0,0, + 0,114,86,0,0,0,90,5,110,101,118,101,114,90,6,97, + 108,119,97,121,115,114,99,0,0,0,114,94,0,0,0,114, + 95,0,0,0,122,22,98,121,116,101,99,111,100,101,32,105, + 115,32,115,116,97,108,101,32,102,111,114,32,122,16,99,111, + 109,112,105,108,101,100,32,109,111,100,117,108,101,32,122,21, + 32,105,115,32,110,111,116,32,97,32,99,111,100,101,32,111, + 98,106,101,99,116,41,20,114,21,0,0,0,90,13,95,99, + 108,97,115,115,105,102,121,95,112,121,99,114,75,0,0,0, + 218,4,95,105,109,112,90,21,99,104,101,99,107,95,104,97, + 115,104,95,98,97,115,101,100,95,112,121,99,115,218,15,95, + 103,101,116,95,112,121,99,95,115,111,117,114,99,101,218,11, + 115,111,117,114,99,101,95,104,97,115,104,90,17,95,82,65, + 87,95,77,65,71,73,67,95,78,85,77,66,69,82,90,18, + 95,98,111,111,115,116,114,97,112,95,101,120,116,101,114,110, + 97,108,90,18,95,118,97,108,105,100,97,116,101,95,104,97, + 115,104,95,112,121,99,218,29,95,103,101,116,95,109,116,105, + 109,101,95,97,110,100,95,115,105,122,101,95,111,102,95,115, + 111,117,114,99,101,114,147,0,0,0,114,2,0,0,0,114, + 76,0,0,0,114,77,0,0,0,218,7,109,97,114,115,104, + 97,108,90,5,108,111,97,100,115,114,15,0,0,0,218,10, + 95,99,111,100,101,95,116,121,112,101,218,9,84,121,112,101, + 69,114,114,111,114,41,14,114,32,0,0,0,114,53,0,0, + 0,114,63,0,0,0,114,38,0,0,0,114,126,0,0,0, + 90,11,101,120,99,95,100,101,116,97,105,108,115,114,129,0, + 0,0,90,10,104,97,115,104,95,98,97,115,101,100,90,12, + 99,104,101,99,107,95,115,111,117,114,99,101,90,12,115,111, + 117,114,99,101,95,98,121,116,101,115,114,150,0,0,0,90, + 12,115,111,117,114,99,101,95,109,116,105,109,101,90,11,115, + 111,117,114,99,101,95,115,105,122,101,114,46,0,0,0,114, + 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,15, + 95,117,110,109,97,114,115,104,97,108,95,99,111,100,101,75, + 2,0,0,115,88,0,0,0,0,2,2,1,2,254,6,5, + 2,1,18,1,14,1,8,2,12,1,4,1,12,1,10,1, + 2,255,2,1,8,255,2,2,10,1,8,1,4,1,4,1, + 2,254,4,5,2,1,4,1,2,0,2,0,2,0,2,255, + 8,2,14,1,10,3,8,255,6,3,6,3,22,1,18,255, + 4,2,4,1,8,255,4,2,4,2,18,1,12,1,16,1, + 114,155,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,4,0,0,0,67,0,0,0,115,28, + 0,0,0,124,0,160,0,100,1,100,2,161,2,125,0,124, + 0,160,0,100,3,100,2,161,2,125,0,124,0,83,0,41, + 4,78,115,2,0,0,0,13,10,243,1,0,0,0,10,243, + 1,0,0,0,13,41,1,114,19,0,0,0,41,1,218,6, + 115,111,117,114,99,101,114,9,0,0,0,114,9,0,0,0, + 114,10,0,0,0,218,23,95,110,111,114,109,97,108,105,122, + 101,95,108,105,110,101,95,101,110,100,105,110,103,115,126,2, + 0,0,115,6,0,0,0,0,1,12,1,12,1,114,159,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,6,0,0,0,67,0,0,0,115,24,0,0,0, + 116,0,124,1,131,1,125,1,116,1,124,1,124,0,100,1, + 100,2,100,3,141,4,83,0,41,4,78,114,74,0,0,0, + 84,41,1,90,12,100,111,110,116,95,105,110,104,101,114,105, + 116,41,2,114,159,0,0,0,218,7,99,111,109,112,105,108, + 101,41,2,114,53,0,0,0,114,158,0,0,0,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,218,15,95,99, + 111,109,112,105,108,101,95,115,111,117,114,99,101,133,2,0, + 0,115,4,0,0,0,0,1,8,1,114,161,0,0,0,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 11,0,0,0,67,0,0,0,115,68,0,0,0,116,0,160, + 1,124,0,100,1,63,0,100,2,23,0,124,0,100,3,63, + 0,100,4,64,0,124,0,100,5,64,0,124,1,100,6,63, + 0,124,1,100,3,63,0,100,7,64,0,124,1,100,5,64, + 0,100,8,20,0,100,9,100,9,100,9,102,9,161,1,83, + 0,41,10,78,233,9,0,0,0,105,188,7,0,0,233,5, + 0,0,0,233,15,0,0,0,233,31,0,0,0,233,11,0, + 0,0,233,63,0,0,0,114,86,0,0,0,114,14,0,0, + 0,41,2,114,131,0,0,0,90,6,109,107,116,105,109,101, + 41,2,218,1,100,114,138,0,0,0,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,218,14,95,112,97,114,115, + 101,95,100,111,115,116,105,109,101,139,2,0,0,115,22,0, + 0,0,0,1,4,1,10,1,10,1,6,1,6,1,10,1, + 10,1,2,0,2,0,2,249,114,169,0,0,0,99,2,0, + 0,0,0,0,0,0,0,0,0,0,6,0,0,0,10,0, + 0,0,67,0,0,0,115,116,0,0,0,122,82,124,1,100, + 1,100,0,133,2,25,0,100,2,107,6,115,22,116,0,130, + 1,124,1,100,0,100,1,133,2,25,0,125,1,124,0,106, + 1,124,1,25,0,125,2,124,2,100,3,25,0,125,3,124, + 2,100,4,25,0,125,4,124,2,100,5,25,0,125,5,116, + 2,124,4,124,3,131,2,124,5,102,2,87,0,83,0,4, + 0,116,3,116,4,116,5,102,3,107,10,114,110,1,0,1, + 0,1,0,89,0,100,6,83,0,88,0,100,0,83,0,41, + 7,78,114,14,0,0,0,169,2,218,1,99,218,1,111,114, + 163,0,0,0,233,6,0,0,0,233,3,0,0,0,41,2, + 114,0,0,0,0,114,0,0,0,0,41,6,218,14,65,115, + 115,101,114,116,105,111,110,69,114,114,111,114,114,28,0,0, + 0,114,169,0,0,0,114,26,0,0,0,218,10,73,110,100, + 101,120,69,114,114,111,114,114,154,0,0,0,41,6,114,32, + 0,0,0,114,13,0,0,0,114,54,0,0,0,114,131,0, + 0,0,114,132,0,0,0,90,17,117,110,99,111,109,112,114, + 101,115,115,101,100,95,115,105,122,101,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,114,151,0,0,0,152,2, + 0,0,115,20,0,0,0,0,1,2,2,20,1,12,1,10, + 3,8,1,8,1,8,1,16,1,20,1,114,151,0,0,0, + 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,86,0,0,0,124,1, + 100,1,100,0,133,2,25,0,100,2,107,6,115,20,116,0, + 130,1,124,1,100,0,100,1,133,2,25,0,125,1,122,14, + 124,0,106,1,124,1,25,0,125,2,87,0,110,22,4,0, + 116,2,107,10,114,68,1,0,1,0,1,0,89,0,100,0, + 83,0,88,0,116,3,124,0,106,4,124,2,131,2,83,0, + 100,0,83,0,41,3,78,114,14,0,0,0,114,170,0,0, + 0,41,5,114,175,0,0,0,114,28,0,0,0,114,26,0, + 0,0,114,52,0,0,0,114,29,0,0,0,41,3,114,32, + 0,0,0,114,13,0,0,0,114,54,0,0,0,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,114,149,0,0, + 0,171,2,0,0,115,14,0,0,0,0,2,20,1,12,2, + 2,1,14,1,14,1,8,2,114,149,0,0,0,99,2,0, + 0,0,0,0,0,0,0,0,0,0,11,0,0,0,9,0, + 0,0,67,0,0,0,115,198,0,0,0,116,0,124,0,124, + 1,131,2,125,2,116,1,68,0,93,160,92,3,125,3,125, + 4,125,5,124,2,124,3,23,0,125,6,116,2,106,3,100, + 1,124,0,106,4,116,5,124,6,100,2,100,3,141,5,1, + 0,122,14,124,0,106,6,124,6,25,0,125,7,87,0,110, + 20,4,0,116,7,107,10,114,88,1,0,1,0,1,0,89, + 0,113,14,88,0,124,7,100,4,25,0,125,8,116,8,124, + 0,106,4,124,7,131,2,125,9,124,4,114,132,116,9,124, + 0,124,8,124,6,124,1,124,9,131,5,125,10,110,10,116, + 10,124,8,124,9,131,2,125,10,124,10,100,0,107,8,114, + 152,113,14,124,7,100,4,25,0,125,8,124,10,124,5,124, + 8,102,3,2,0,1,0,83,0,113,14,116,11,100,5,124, + 1,155,2,157,2,124,1,100,6,141,2,130,1,100,0,83, + 0,41,7,78,122,13,116,114,121,105,110,103,32,123,125,123, + 125,123,125,114,86,0,0,0,41,1,90,9,118,101,114,98, + 111,115,105,116,121,114,0,0,0,0,114,57,0,0,0,114, + 58,0,0,0,41,12,114,36,0,0,0,114,89,0,0,0, + 114,76,0,0,0,114,77,0,0,0,114,29,0,0,0,114, + 20,0,0,0,114,28,0,0,0,114,26,0,0,0,114,52, + 0,0,0,114,155,0,0,0,114,161,0,0,0,114,3,0, + 0,0,41,11,114,32,0,0,0,114,38,0,0,0,114,13, + 0,0,0,114,90,0,0,0,114,91,0,0,0,114,47,0, + 0,0,114,63,0,0,0,114,54,0,0,0,114,40,0,0, + 0,114,126,0,0,0,114,46,0,0,0,114,9,0,0,0, + 114,9,0,0,0,114,10,0,0,0,114,44,0,0,0,186, + 2,0,0,115,36,0,0,0,0,1,10,1,14,1,8,1, + 22,1,2,1,14,1,14,1,6,2,8,1,12,1,4,1, + 18,2,10,1,8,3,2,1,8,1,16,2,114,44,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,60,0,0,0,101, + 0,90,1,100,0,90,2,100,1,90,3,100,2,90,4,100, + 3,100,4,132,0,90,5,100,5,100,6,132,0,90,6,100, + 7,100,8,132,0,90,7,100,9,100,10,132,0,90,8,100, + 11,100,12,132,0,90,9,100,13,83,0,41,14,114,80,0, + 0,0,122,165,80,114,105,118,97,116,101,32,99,108,97,115, + 115,32,117,115,101,100,32,116,111,32,115,117,112,112,111,114, + 116,32,90,105,112,73,109,112,111,114,116,46,103,101,116,95, + 114,101,115,111,117,114,99,101,95,114,101,97,100,101,114,40, + 41,46,10,10,32,32,32,32,84,104,105,115,32,99,108,97, + 115,115,32,105,115,32,97,108,108,111,119,101,100,32,116,111, + 32,114,101,102,101,114,101,110,99,101,32,97,108,108,32,116, + 104,101,32,105,110,110,97,114,100,115,32,97,110,100,32,112, + 114,105,118,97,116,101,32,112,97,114,116,115,32,111,102,10, + 32,32,32,32,116,104,101,32,122,105,112,105,109,112,111,114, + 116,101,114,46,10,32,32,32,32,70,99,3,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,67, + 0,0,0,115,16,0,0,0,124,1,124,0,95,0,124,2, + 124,0,95,1,100,0,83,0,114,88,0,0,0,41,2,114, + 4,0,0,0,114,38,0,0,0,41,3,114,32,0,0,0, + 114,4,0,0,0,114,38,0,0,0,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,114,34,0,0,0,220,2, + 0,0,115,4,0,0,0,0,1,6,1,122,33,95,90,105, + 112,73,109,112,111,114,116,82,101,115,111,117,114,99,101,82, + 101,97,100,101,114,46,95,95,105,110,105,116,95,95,99,2, + 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,8, + 0,0,0,67,0,0,0,115,92,0,0,0,124,0,106,0, + 160,1,100,1,100,2,161,2,125,2,124,2,155,0,100,2, + 124,1,155,0,157,3,125,3,100,3,100,4,108,2,109,3, + 125,4,1,0,122,18,124,4,124,0,106,4,160,5,124,3, + 161,1,131,1,87,0,83,0,4,0,116,6,107,10,114,86, + 1,0,1,0,1,0,116,7,124,3,131,1,130,1,89,0, + 110,2,88,0,100,0,83,0,41,5,78,114,85,0,0,0, + 114,109,0,0,0,114,0,0,0,0,41,1,218,7,66,121, + 116,101,115,73,79,41,8,114,38,0,0,0,114,19,0,0, + 0,90,2,105,111,114,177,0,0,0,114,4,0,0,0,114, + 55,0,0,0,114,22,0,0,0,218,17,70,105,108,101,78, + 111,116,70,111,117,110,100,69,114,114,111,114,41,5,114,32, + 0,0,0,218,8,114,101,115,111,117,114,99,101,218,16,102, + 117,108,108,110,97,109,101,95,97,115,95,112,97,116,104,114, + 13,0,0,0,114,177,0,0,0,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,218,13,111,112,101,110,95,114, + 101,115,111,117,114,99,101,224,2,0,0,115,14,0,0,0, + 0,1,14,1,14,1,12,1,2,1,18,1,14,1,122,38, + 95,90,105,112,73,109,112,111,114,116,82,101,115,111,117,114, + 99,101,82,101,97,100,101,114,46,111,112,101,110,95,114,101, + 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, + 8,0,0,0,116,0,130,1,100,0,83,0,114,88,0,0, + 0,41,1,114,178,0,0,0,41,2,114,32,0,0,0,114, + 179,0,0,0,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,218,13,114,101,115,111,117,114,99,101,95,112,97, + 116,104,233,2,0,0,115,2,0,0,0,0,4,122,38,95, + 90,105,112,73,109,112,111,114,116,82,101,115,111,117,114,99, + 101,82,101,97,100,101,114,46,114,101,115,111,117,114,99,101, + 95,112,97,116,104,99,2,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,8,0,0,0,67,0,0,0,115,72, + 0,0,0,124,0,106,0,160,1,100,1,100,2,161,2,125, + 2,124,2,155,0,100,2,124,1,155,0,157,3,125,3,122, + 16,124,0,106,2,160,3,124,3,161,1,1,0,87,0,110, + 22,4,0,116,4,107,10,114,66,1,0,1,0,1,0,89, + 0,100,3,83,0,88,0,100,4,83,0,41,5,78,114,85, + 0,0,0,114,109,0,0,0,70,84,41,5,114,38,0,0, + 0,114,19,0,0,0,114,4,0,0,0,114,55,0,0,0, + 114,22,0,0,0,41,4,114,32,0,0,0,114,59,0,0, + 0,114,180,0,0,0,114,13,0,0,0,114,9,0,0,0, + 114,9,0,0,0,114,10,0,0,0,218,11,105,115,95,114, + 101,115,111,117,114,99,101,239,2,0,0,115,14,0,0,0, + 0,3,14,1,14,1,2,1,16,1,14,1,8,1,122,36, + 95,90,105,112,73,109,112,111,114,116,82,101,115,111,117,114, + 99,101,82,101,97,100,101,114,46,105,115,95,114,101,115,111, + 117,114,99,101,99,1,0,0,0,0,0,0,0,0,0,0, + 0,9,0,0,0,9,0,0,0,99,0,0,0,115,186,0, + 0,0,100,1,100,2,108,0,109,1,125,1,1,0,124,1, + 124,0,106,2,160,3,124,0,106,4,161,1,131,1,125,2, + 124,2,160,5,124,0,106,2,106,6,161,1,125,3,124,3, + 106,7,100,3,107,2,115,58,116,8,130,1,124,3,106,9, + 125,4,116,10,131,0,125,5,124,0,106,2,106,11,68,0, + 93,102,125,6,122,18,124,1,124,6,131,1,160,5,124,4, + 161,1,125,7,87,0,110,24,4,0,116,12,107,10,114,124, + 1,0,1,0,1,0,89,0,113,78,89,0,110,2,88,0, + 124,7,106,9,106,7,125,8,116,13,124,8,131,1,100,1, + 107,2,114,156,124,7,106,7,86,0,1,0,113,78,124,8, + 124,5,107,7,114,78,124,5,160,14,124,8,161,1,1,0, + 124,8,86,0,1,0,113,78,100,0,83,0,41,4,78,114, + 0,0,0,0,41,1,218,4,80,97,116,104,114,60,0,0, + 0,41,15,90,7,112,97,116,104,108,105,98,114,184,0,0, + 0,114,4,0,0,0,114,56,0,0,0,114,38,0,0,0, + 90,11,114,101,108,97,116,105,118,101,95,116,111,114,29,0, + 0,0,114,59,0,0,0,114,175,0,0,0,90,6,112,97, + 114,101,110,116,218,3,115,101,116,114,28,0,0,0,114,23, + 0,0,0,114,51,0,0,0,218,3,97,100,100,41,9,114, + 32,0,0,0,114,184,0,0,0,90,13,102,117,108,108,110, + 97,109,101,95,112,97,116,104,90,13,114,101,108,97,116,105, + 118,101,95,112,97,116,104,90,12,112,97,99,107,97,103,101, + 95,112,97,116,104,90,12,115,117,98,100,105,114,115,95,115, + 101,101,110,218,8,102,105,108,101,110,97,109,101,90,8,114, + 101,108,97,116,105,118,101,90,11,112,97,114,101,110,116,95, + 110,97,109,101,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,218,8,99,111,110,116,101,110,116,115,250,2,0, + 0,115,34,0,0,0,0,8,12,1,18,1,14,3,14,1, + 6,1,6,1,12,1,2,1,18,1,14,1,10,5,8,1, + 12,1,10,1,8,1,10,1,122,33,95,90,105,112,73,109, + 112,111,114,116,82,101,115,111,117,114,99,101,82,101,97,100, + 101,114,46,99,111,110,116,101,110,116,115,78,41,10,114,6, + 0,0,0,114,7,0,0,0,114,8,0,0,0,114,84,0, + 0,0,114,81,0,0,0,114,34,0,0,0,114,181,0,0, + 0,114,182,0,0,0,114,183,0,0,0,114,188,0,0,0, + 114,9,0,0,0,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,114,80,0,0,0,212,2,0,0,115,14,0, + 0,0,8,1,4,5,4,2,8,4,8,9,8,6,8,11, + 114,80,0,0,0,41,45,114,84,0,0,0,90,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,21,0,0,0,114,1,0, + 0,0,114,2,0,0,0,90,17,95,102,114,111,122,101,110, + 95,105,109,112,111,114,116,108,105,98,114,76,0,0,0,114, + 148,0,0,0,114,110,0,0,0,114,152,0,0,0,114,67, + 0,0,0,114,131,0,0,0,90,7,95,95,97,108,108,95, + 95,114,20,0,0,0,90,15,112,97,116,104,95,115,101,112, + 97,114,97,116,111,114,115,114,18,0,0,0,114,75,0,0, + 0,114,3,0,0,0,114,25,0,0,0,218,4,116,121,112, + 101,114,70,0,0,0,114,113,0,0,0,114,115,0,0,0, + 114,117,0,0,0,114,4,0,0,0,114,89,0,0,0,114, + 36,0,0,0,114,37,0,0,0,114,35,0,0,0,114,27, + 0,0,0,114,122,0,0,0,114,142,0,0,0,114,144,0, + 0,0,114,52,0,0,0,114,147,0,0,0,114,155,0,0, + 0,218,8,95,95,99,111,100,101,95,95,114,153,0,0,0, + 114,159,0,0,0,114,161,0,0,0,114,169,0,0,0,114, + 151,0,0,0,114,149,0,0,0,114,44,0,0,0,114,80, + 0,0,0,114,9,0,0,0,114,9,0,0,0,114,9,0, + 0,0,114,10,0,0,0,218,8,60,109,111,100,117,108,101, + 62,1,0,0,0,115,88,0,0,0,4,16,8,1,16,1, + 8,1,8,1,8,1,8,1,8,1,8,2,8,3,6,1, + 14,3,16,4,4,2,8,2,4,1,4,1,4,2,14,127, + 0,127,0,1,12,1,12,1,2,1,2,252,4,9,8,4, + 8,9,8,31,8,126,2,254,2,29,4,5,8,21,8,46, + 8,10,8,46,10,5,8,7,8,6,8,13,8,19,8,15, + 8,26, }; diff --git a/Python/initconfig.c b/Python/initconfig.c index 66b1b305a56033..a41a3292d3e2c1 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -1,12 +1,13 @@ #include "Python.h" #include "osdefs.h" /* DELIM */ -#include "pycore_initconfig.h" #include "pycore_fileutils.h" #include "pycore_getopt.h" +#include "pycore_initconfig.h" +#include "pycore_pathconfig.h" +#include "pycore_pyerrors.h" #include "pycore_pylifecycle.h" #include "pycore_pymem.h" #include "pycore_pystate.h" /* _PyRuntime */ -#include "pycore_pathconfig.h" #include /* setlocale() */ #ifdef HAVE_LANGINFO_H # include /* nl_langinfo(CODESET) */ @@ -83,8 +84,8 @@ static const char usage_5[] = "PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n"; static const char usage_6[] = "PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n" -" to seed the hashes of str, bytes and datetime objects. It can also be\n" -" set to an integer in the range [0,4294967295] to get hash values with a\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" "PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n" " on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n" @@ -272,7 +273,7 @@ _PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2) return 0; } - PyWideStringList copy = PyWideStringList_INIT; + PyWideStringList copy = _PyWideStringList_INIT; size_t size = list2->length * sizeof(list2->items[0]); copy.items = PyMem_RawMalloc(size); @@ -297,32 +298,53 @@ _PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2) PyStatus -PyWideStringList_Append(PyWideStringList *list, const wchar_t *item) +PyWideStringList_Insert(PyWideStringList *list, + Py_ssize_t index, const wchar_t *item) { - if (list->length == PY_SSIZE_T_MAX) { - /* lenght+1 would overflow */ + Py_ssize_t len = list->length; + if (len == PY_SSIZE_T_MAX) { + /* length+1 would overflow */ return _PyStatus_NO_MEMORY(); } + if (index < 0) { + return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0"); + } + if (index > len) { + index = len; + } wchar_t *item2 = _PyMem_RawWcsdup(item); if (item2 == NULL) { return _PyStatus_NO_MEMORY(); } - size_t size = (list->length + 1) * sizeof(list->items[0]); + size_t size = (len + 1) * sizeof(list->items[0]); wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size); if (items2 == NULL) { PyMem_RawFree(item2); return _PyStatus_NO_MEMORY(); } - items2[list->length] = item2; + if (index < len) { + memmove(&items2[index + 1], + &items2[index], + (len - index) * sizeof(items2[0])); + } + + items2[index] = item2; list->items = items2; list->length++; return _PyStatus_OK(); } +PyStatus +PyWideStringList_Append(PyWideStringList *list, const wchar_t *item) +{ + return PyWideStringList_Insert(list, list->length, item); +} + + PyStatus _PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2) { @@ -506,6 +528,7 @@ Py_GetArgcArgv(int *argc, wchar_t ***argv) ? _PyStatus_ERR("cannot decode " NAME) \ : _PyStatus_NO_MEMORY()) + /* Free memory allocated in config, but don't clear all attributes */ void PyConfig_Clear(PyConfig *config) @@ -528,6 +551,7 @@ PyConfig_Clear(PyConfig *config) config->module_search_paths_set = 0; CLEAR(config->executable); + CLEAR(config->base_executable); CLEAR(config->prefix); CLEAR(config->base_prefix); CLEAR(config->exec_prefix); @@ -550,7 +574,6 @@ _PyConfig_InitCompatConfig(PyConfig *config) { memset(config, 0, sizeof(*config)); - config->_config_version = _Py_CONFIG_VERSION; config->_config_init = (int)_PyConfig_INIT_COMPAT; config->isolated = -1; config->use_environment = -1; @@ -608,7 +631,7 @@ config_init_defaults(PyConfig *config) } -PyStatus +void PyConfig_InitPythonConfig(PyConfig *config) { config_init_defaults(config); @@ -616,12 +639,10 @@ PyConfig_InitPythonConfig(PyConfig *config) config->_config_init = (int)_PyConfig_INIT_PYTHON; config->configure_c_stdio = 1; config->parse_argv = 1; - - return _PyStatus_OK(); } -PyStatus +void PyConfig_InitIsolatedConfig(PyConfig *config) { config_init_defaults(config); @@ -639,8 +660,6 @@ PyConfig_InitIsolatedConfig(PyConfig *config) #ifdef MS_WINDOWS config->legacy_windows_stdio = 0; #endif - - return _PyStatus_OK(); } @@ -719,6 +738,7 @@ PyStatus _PyConfig_Copy(PyConfig *config, const PyConfig *config2) { PyStatus status; + PyConfig_Clear(config); #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR @@ -731,7 +751,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) } while (0) #define COPY_WSTRLIST(LIST) \ do { \ - if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0 ) { \ + if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \ return _PyStatus_NO_MEMORY(); \ } \ } while (0) @@ -765,6 +785,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_ATTR(module_search_paths_set); COPY_WSTR_ATTR(executable); + COPY_WSTR_ATTR(base_executable); COPY_WSTR_ATTR(prefix); COPY_WSTR_ATTR(base_prefix); COPY_WSTR_ATTR(exec_prefix); @@ -865,6 +886,7 @@ config_as_dict(const PyConfig *config) SET_ITEM_WSTR(home); SET_ITEM_WSTRLIST(module_search_paths); SET_ITEM_WSTR(executable); + SET_ITEM_WSTR(base_executable); SET_ITEM_WSTR(prefix); SET_ITEM_WSTR(base_prefix); SET_ITEM_WSTR(exec_prefix); @@ -2025,62 +2047,83 @@ config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions) static PyStatus -config_add_warnoption(PyConfig *config, const wchar_t *option) +warnoptions_append(PyConfig *config, PyWideStringList *options, + const wchar_t *option) { + /* config_init_warnoptions() add existing config warnoptions at the end: + ensure that the new option is not already present in this list to + prevent change the options order whne config_init_warnoptions() is + called twice. */ if (_PyWideStringList_Find(&config->warnoptions, option)) { /* Already present: do nothing */ return _PyStatus_OK(); } - return PyWideStringList_Append(&config->warnoptions, option); + if (_PyWideStringList_Find(options, option)) { + /* Already present: do nothing */ + return _PyStatus_OK(); + } + return PyWideStringList_Append(options, option); +} + + +static PyStatus +warnoptions_extend(PyConfig *config, PyWideStringList *options, + const PyWideStringList *options2) +{ + const Py_ssize_t len = options2->length; + wchar_t *const *items = options2->items; + + for (Py_ssize_t i = 0; i < len; i++) { + PyStatus status = warnoptions_append(config, options, items[i]); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + return _PyStatus_OK(); } static PyStatus config_init_warnoptions(PyConfig *config, const PyWideStringList *cmdline_warnoptions, - const PyWideStringList *env_warnoptions) + const PyWideStringList *env_warnoptions, + const PyWideStringList *sys_warnoptions) { PyStatus status; + PyWideStringList options = _PyWideStringList_INIT; - /* The priority order for warnings configuration is (highest precedence - * first): + /* Priority of warnings options, lowest to highest: * - * - the BytesWarning filter, if needed ('-b', '-bb') - * - any '-W' command line options; then - * - the 'PYTHONWARNINGS' environment variable; then - * - the dev mode filter ('-X dev', 'PYTHONDEVMODE'); then * - any implicit filters added by _warnings.c/warnings.py + * - PyConfig.dev_mode: "default" filter + * - PYTHONWARNINGS environment variable + * - '-W' command line options + * - PyConfig.bytes_warning ('-b' and '-bb' command line options): + * "default::BytesWarning" or "error::BytesWarning" filter + * - early PySys_AddWarnOption() calls + * - PyConfig.warnoptions * - * All settings except the last are passed to the warnings module via - * the `sys.warnoptions` list. Since the warnings module works on the basis - * of "the most recently added filter will be checked first", we add - * the lowest precedence entries first so that later entries override them. + * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings + * module works on the basis of "the most recently added filter will be + * checked first", we add the lowest precedence entries first so that later + * entries override them. */ if (config->dev_mode) { - status = config_add_warnoption(config, L"default"); + status = warnoptions_append(config, &options, L"default"); if (_PyStatus_EXCEPTION(status)) { - return status; + goto error; } } - Py_ssize_t i; - const PyWideStringList *options; - - options = env_warnoptions; - for (i = 0; i < options->length; i++) { - status = config_add_warnoption(config, options->items[i]); - if (_PyStatus_EXCEPTION(status)) { - return status; - } + status = warnoptions_extend(config, &options, env_warnoptions); + if (_PyStatus_EXCEPTION(status)) { + goto error; } - options = cmdline_warnoptions; - for (i = 0; i < options->length; i++) { - status = config_add_warnoption(config, options->items[i]); - if (_PyStatus_EXCEPTION(status)) { - return status; - } + status = warnoptions_extend(config, &options, cmdline_warnoptions); + if (_PyStatus_EXCEPTION(status)) { + goto error; } /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c @@ -2095,12 +2138,30 @@ config_init_warnoptions(PyConfig *config, else { filter = L"default::BytesWarning"; } - status = config_add_warnoption(config, filter); + status = warnoptions_append(config, &options, filter); if (_PyStatus_EXCEPTION(status)) { - return status; + goto error; } } + + status = warnoptions_extend(config, &options, sys_warnoptions); + if (_PyStatus_EXCEPTION(status)) { + goto error; + } + + /* Always add all PyConfig.warnoptions options */ + status = _PyWideStringList_Extend(&options, &config->warnoptions); + if (_PyStatus_EXCEPTION(status)) { + goto error; + } + + _PyWideStringList_Clear(&config->warnoptions); + config->warnoptions = options; return _PyStatus_OK(); + +error: + _PyWideStringList_Clear(&options); + return status; } @@ -2108,7 +2169,7 @@ static PyStatus config_update_argv(PyConfig *config, Py_ssize_t opt_index) { const PyWideStringList *cmdline_argv = &config->argv; - PyWideStringList config_argv = PyWideStringList_INIT; + PyWideStringList config_argv = _PyWideStringList_INIT; /* Copy argv to be able to modify it (to force -c/-m) */ if (cmdline_argv->length <= opt_index) { @@ -2166,7 +2227,11 @@ core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline) } PyPreConfig preconfig; - _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig); + + status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; + } _PyPreConfig_GetConfig(&preconfig, config); @@ -2187,8 +2252,9 @@ static PyStatus config_read_cmdline(PyConfig *config) { PyStatus status; - PyWideStringList cmdline_warnoptions = PyWideStringList_INIT; - PyWideStringList env_warnoptions = PyWideStringList_INIT; + PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT; + PyWideStringList env_warnoptions = _PyWideStringList_INIT; + PyWideStringList sys_warnoptions = _PyWideStringList_INIT; if (config->parse_argv < 0) { config->parse_argv = 1; @@ -2221,8 +2287,16 @@ config_read_cmdline(PyConfig *config) } } + /* Handle early PySys_AddWarnOption() calls */ + status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + status = config_init_warnoptions(config, - &cmdline_warnoptions, &env_warnoptions); + &cmdline_warnoptions, + &env_warnoptions, + &sys_warnoptions); if (_PyStatus_EXCEPTION(status)) { goto done; } @@ -2232,6 +2306,7 @@ config_read_cmdline(PyConfig *config) done: _PyWideStringList_Clear(&cmdline_warnoptions); _PyWideStringList_Clear(&env_warnoptions); + _PyWideStringList_Clear(&sys_warnoptions); return status; } @@ -2274,6 +2349,23 @@ PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv) } +PyStatus +PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list, + Py_ssize_t length, wchar_t **items) +{ + PyStatus status = _Py_PreInitializeFromConfig(config, NULL); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + PyWideStringList list2 = {.length = length, .items = items}; + if (_PyWideStringList_Copy(list, &list2) < 0) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); +} + + /* Read the configuration into PyConfig from: * Command line arguments @@ -2285,7 +2377,7 @@ PyStatus PyConfig_Read(PyConfig *config) { PyStatus status; - PyWideStringList orig_argv = PyWideStringList_INIT; + PyWideStringList orig_argv = _PyWideStringList_INIT; status = _Py_PreInitializeFromConfig(config, NULL); if (_PyStatus_EXCEPTION(status)) { @@ -2315,6 +2407,12 @@ PyConfig_Read(PyConfig *config) goto done; } + /* Handle early PySys_AddXOption() calls */ + status = _PySys_ReadPreinitXOptions(config); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + status = config_read(config); if (_PyStatus_EXCEPTION(status)) { goto done; @@ -2357,6 +2455,7 @@ PyConfig_Read(PyConfig *config) assert(config->module_search_paths_set != 0); /* don't check config->module_search_paths */ assert(config->executable != NULL); + assert(config->base_executable != NULL); assert(config->prefix != NULL); assert(config->base_prefix != NULL); assert(config->exec_prefix != NULL); @@ -2435,3 +2534,98 @@ _Py_GetConfigsAsDict(void) Py_XDECREF(dict); return NULL; } + + +static void +init_dump_ascii_wstr(const wchar_t *str) +{ + if (str == NULL) { + PySys_WriteStderr("(not set)"); + return; + } + + PySys_WriteStderr("'"); + for (; *str != L'\0'; str++) { + wchar_t ch = *str; + if (ch == L'\'') { + PySys_WriteStderr("\\'"); + } else if (0x20 <= ch && ch < 0x7f) { + PySys_WriteStderr("%lc", ch); + } + else if (ch <= 0xff) { + PySys_WriteStderr("\\x%02x", ch); + } +#if SIZEOF_WCHAR_T > 2 + else if (ch > 0xffff) { + PySys_WriteStderr("\\U%08x", ch); + } +#endif + else { + PySys_WriteStderr("\\u%04x", ch); + } + } + PySys_WriteStderr("'"); +} + + +/* Dump the Python path configuration into sys.stderr */ +void +_Py_DumpPathConfig(PyThreadState *tstate) +{ + PyObject *exc_type, *exc_value, *exc_tb; + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + + PySys_WriteStderr("Python path configuration:\n"); + +#define DUMP_CONFIG(NAME, FIELD) \ + do { \ + PySys_WriteStderr(" " NAME " = "); \ + init_dump_ascii_wstr(config->FIELD); \ + PySys_WriteStderr("\n"); \ + } while (0) + + PyConfig *config = &tstate->interp->config; + DUMP_CONFIG("PYTHONHOME", home); + DUMP_CONFIG("PYTHONPATH", pythonpath_env); + DUMP_CONFIG("program name", program_name); + 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(" import site = %i\n", config->site_import); +#undef DUMP_CONFIG + +#define DUMP_SYS(NAME) \ + do { \ + obj = PySys_GetObject(#NAME); \ + PySys_FormatStderr(" sys.%s = ", #NAME); \ + if (obj != NULL) { \ + PySys_FormatStderr("%A", obj); \ + } \ + else { \ + PySys_WriteStderr("(not set)"); \ + } \ + PySys_FormatStderr("\n"); \ + } while (0) + + PyObject *obj; + DUMP_SYS(_base_executable); + DUMP_SYS(base_prefix); + DUMP_SYS(base_exec_prefix); + DUMP_SYS(executable); + DUMP_SYS(prefix); + DUMP_SYS(exec_prefix); +#undef DUMP_SYS + + PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */ + if (sys_path != NULL && PyList_Check(sys_path)) { + PySys_WriteStderr(" sys.path = [\n"); + Py_ssize_t len = PyList_GET_SIZE(sys_path); + for (Py_ssize_t i=0; i < len; i++) { + PyObject *path = PyList_GET_ITEM(sys_path, i); + PySys_FormatStderr(" %A,\n", path); + } + PySys_WriteStderr(" ]\n"); + } + + _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); +} diff --git a/Python/marshal.c b/Python/marshal.c index caaddfe9e44e49..b2daff2c8a3bef 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -1396,7 +1396,7 @@ r_object(RFILE *p) if (lnotab == NULL) goto code_error; - v = (PyObject *) PyCode_New( + v = (PyObject *) PyCode_NewWithPosOnlyArgs( argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, diff --git a/Python/pathconfig.c b/Python/pathconfig.c index ec67405a28d054..7f3fdcc103f7b0 100644 --- a/Python/pathconfig.c +++ b/Python/pathconfig.c @@ -15,11 +15,15 @@ extern "C" { _PyPathConfig _Py_path_config = _PyPathConfig_INIT; +#ifdef MS_WINDOWS +wchar_t *_Py_dll_path = NULL; +#endif static int copy_wstr(wchar_t **dst, const wchar_t *src) { + assert(*dst == NULL); if (src != NULL) { *dst = _PyMem_RawWcsdup(src); if (*dst == NULL) { @@ -48,100 +52,49 @@ pathconfig_clear(_PyPathConfig *config) ATTR = NULL; \ } while (0) - CLEAR(config->prefix); CLEAR(config->program_full_path); + CLEAR(config->prefix); CLEAR(config->exec_prefix); -#ifdef MS_WINDOWS - CLEAR(config->dll_path); -#endif CLEAR(config->module_search_path); - CLEAR(config->home); CLEAR(config->program_name); + CLEAR(config->home); +#ifdef MS_WINDOWS + CLEAR(config->base_executable); +#endif + #undef CLEAR PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } -/* Calculate the path configuration: initialize pathconfig from config */ static PyStatus -pathconfig_calculate(_PyPathConfig *pathconfig, const PyConfig *config) -{ - PyStatus status; - _PyPathConfig new_config = _PyPathConfig_INIT; - - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - /* Calculate program_full_path, prefix, exec_prefix, - dll_path (Windows), and module_search_path */ - status = _PyPathConfig_Calculate(&new_config, config); - if (_PyStatus_EXCEPTION(status)) { - goto error; - } - - /* Copy home and program_name from config */ - if (copy_wstr(&new_config.home, config->home) < 0) { - status = _PyStatus_NO_MEMORY(); - goto error; - } - if (copy_wstr(&new_config.program_name, config->program_name) < 0) { - status = _PyStatus_NO_MEMORY(); - goto error; - } - - pathconfig_clear(pathconfig); - *pathconfig = new_config; - - status = _PyStatus_OK(); - goto done; - -error: - pathconfig_clear(&new_config); - -done: - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return status; -} - - -PyStatus -_PyPathConfig_SetGlobal(const _PyPathConfig *config) +pathconfig_copy(_PyPathConfig *config, const _PyPathConfig *config2) { - PyStatus status; - _PyPathConfig new_config = _PyPathConfig_INIT; - - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + pathconfig_clear(config); #define COPY_ATTR(ATTR) \ do { \ - if (copy_wstr(&new_config.ATTR, config->ATTR) < 0) { \ - pathconfig_clear(&new_config); \ - status = _PyStatus_NO_MEMORY(); \ - goto done; \ + 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); -#ifdef MS_WINDOWS - COPY_ATTR(dll_path); -#endif COPY_ATTR(module_search_path); 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 - pathconfig_clear(&_Py_path_config); - /* Steal new_config strings; don't clear new_config */ - _Py_path_config = new_config; - - status = _PyStatus_OK(); +#undef COPY_ATTR -done: - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return status; + return _PyStatus_OK(); } @@ -152,6 +105,10 @@ _PyPathConfig_ClearGlobal(void) _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); pathconfig_clear(&_Py_path_config); +#ifdef MS_WINDOWS + PyMem_RawFree(_Py_dll_path); + _Py_dll_path = NULL; +#endif PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } @@ -176,7 +133,7 @@ _PyWideStringList_Join(const PyWideStringList *list, wchar_t sep) for (Py_ssize_t i=0; i < list->length; i++) { wchar_t *path = list->items[i]; if (i != 0) { - *str++ = SEP; + *str++ = sep; } len = wcslen(path); memcpy(str, path, len * sizeof(wchar_t)); @@ -188,47 +145,65 @@ _PyWideStringList_Join(const PyWideStringList *list, wchar_t sep) } -/* Set the global path configuration from config. */ -PyStatus -_PyConfig_SetPathConfig(const PyConfig *config) +#ifdef MS_WINDOWS +/* Initialize _Py_dll_path on Windows. Do nothing on other platforms. */ +static PyStatus +_PyPathConfig_InitDLLPath(void) { + if (_Py_dll_path == NULL) { + /* Already set: nothing to do */ + return _PyStatus_OK(); + } + PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - PyStatus status; - _PyPathConfig pathconfig = _PyPathConfig_INIT; + _Py_dll_path = _Py_GetDLLPath(); - pathconfig.module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM); - if (pathconfig.module_search_path == NULL) { - goto no_memory; - } + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - if (copy_wstr(&pathconfig.program_full_path, config->executable) < 0) { - goto no_memory; - } - if (copy_wstr(&pathconfig.prefix, config->prefix) < 0) { - goto no_memory; + if (_Py_dll_path == NULL) { + return _PyStatus_NO_MEMORY(); } - if (copy_wstr(&pathconfig.exec_prefix, config->exec_prefix) < 0) { - goto no_memory; + return _PyStatus_OK(); +} +#endif + + +static PyStatus +pathconfig_set_from_config(_PyPathConfig *pathconfig, 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_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; \ + } \ + } + + COPY_CONFIG(program_full_path, executable); + COPY_CONFIG(prefix, prefix); + COPY_CONFIG(exec_prefix, exec_prefix); + COPY_CONFIG(program_name, program_name); + COPY_CONFIG(home, home); #ifdef MS_WINDOWS - pathconfig.dll_path = _Py_GetDLLPath(); - if (pathconfig.dll_path == NULL) { - goto no_memory; - } + COPY_CONFIG(base_executable, base_executable); #endif - if (copy_wstr(&pathconfig.program_name, config->program_name) < 0) { - goto no_memory; - } - if (copy_wstr(&pathconfig.home, config->home) < 0) { - goto no_memory; - } - status = _PyPathConfig_SetGlobal(&pathconfig); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } +#undef COPY_CONFIG status = _PyStatus_OK(); goto done; @@ -237,12 +212,25 @@ _PyConfig_SetPathConfig(const PyConfig *config) status = _PyStatus_NO_MEMORY(); done: - pathconfig_clear(&pathconfig); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return status; } +PyStatus +_PyConfig_WritePathConfig(const PyConfig *config) +{ +#ifdef MS_WINDOWS + PyStatus status = _PyPathConfig_InitDLLPath(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } +#endif + + return pathconfig_set_from_config(&_Py_path_config, config); +} + + static PyStatus config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig) { @@ -283,6 +271,61 @@ config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig) } +/* Calculate the path configuration: + + - exec_prefix + - module_search_path + - 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_calculate(_PyPathConfig *pathconfig, const PyConfig *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 (_Py_path_config.module_search_path == NULL) { + status = _PyPathConfig_Calculate(pathconfig, config); + } + else { + /* Py_SetPath() has been called: avoid _PyPathConfig_Calculate() */ + } + +done: + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return status; +} + + static PyStatus config_calculate_pathconfig(PyConfig *config) { @@ -291,50 +334,57 @@ config_calculate_pathconfig(PyConfig *config) status = pathconfig_calculate(&pathconfig, config); if (_PyStatus_EXCEPTION(status)) { - goto error; + goto done; } if (!config->module_search_paths_set) { status = config_init_module_search_paths(config, &pathconfig); if (_PyStatus_EXCEPTION(status)) { - goto error; + goto done; } } - if (config->executable == NULL) { - if (copy_wstr(&config->executable, - pathconfig.program_full_path) < 0) { - goto no_memory; +#define COPY_ATTR(PATH_ATTR, CONFIG_ATTR) \ + if (config->CONFIG_ATTR == NULL) { \ + if (copy_wstr(&config->CONFIG_ATTR, pathconfig.PATH_ATTR) < 0) { \ + goto no_memory; \ + } \ } - } - if (config->prefix == NULL) { - if (copy_wstr(&config->prefix, pathconfig.prefix) < 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 */ } - - if (config->exec_prefix == NULL) { - if (copy_wstr(&config->exec_prefix, - pathconfig.exec_prefix) < 0) { - goto no_memory; - } + else { + COPY_ATTR(base_executable, base_executable); } +#endif + + COPY_ATTR(program_full_path, executable); + COPY_ATTR(prefix, prefix); + COPY_ATTR(exec_prefix, exec_prefix); +#undef COPY_ATTR + +#ifdef MS_WINDOWS + /* If a ._pth file is found: isolated and site_import are overriden */ if (pathconfig.isolated != -1) { config->isolated = pathconfig.isolated; } if (pathconfig.site_import != -1) { config->site_import = pathconfig.site_import; } +#endif - pathconfig_clear(&pathconfig); - return _PyStatus_OK(); + status = _PyStatus_OK(); + goto done; no_memory: status = _PyStatus_NO_MEMORY(); -error: +done: pathconfig_clear(&pathconfig); return status; } @@ -345,9 +395,9 @@ _PyConfig_InitPathConfig(PyConfig *config) { /* Do we need to calculate the path? */ if (!config->module_search_paths_set - || (config->executable == NULL) - || (config->prefix == NULL) - || (config->exec_prefix == NULL)) + || config->executable == NULL + || config->prefix == NULL + || config->exec_prefix == NULL) { PyStatus status = config_calculate_pathconfig(config); if (_PyStatus_EXCEPTION(status)) { @@ -367,38 +417,69 @@ _PyConfig_InitPathConfig(PyConfig *config) return _PyStatus_NO_MEMORY(); } } + + if (config->base_executable == NULL) { + if (copy_wstr(&config->base_executable, + config->executable) < 0) { + return _PyStatus_NO_MEMORY(); + } + } + return _PyStatus_OK(); } -static void -pathconfig_global_init(void) +static PyStatus +pathconfig_global_read(_PyPathConfig *pathconfig) { - if (_Py_path_config.module_search_path != NULL) { - /* Already initialized */ - return; - } - - PyStatus status; PyConfig config; _PyConfig_InitCompatConfig(&config); - status = PyConfig_Read(&config); + /* Call _PyConfig_InitPathConfig() */ + PyStatus status = PyConfig_Read(&config); if (_PyStatus_EXCEPTION(status)) { - goto error; + goto done; } - status = _PyConfig_SetPathConfig(&config); + status = pathconfig_set_from_config(pathconfig, &config); + +done: + PyConfig_Clear(&config); + return status; +} + + +static void +pathconfig_global_init(void) +{ + PyStatus status; + +#ifdef MS_WINDOWS + status = _PyPathConfig_InitDLLPath(); if (_PyStatus_EXCEPTION(status)) { - goto error; + Py_ExitStatusException(status); } +#endif - PyConfig_Clear(&config); - return; + if (_Py_path_config.module_search_path == NULL) { + status = pathconfig_global_read(&_Py_path_config); + if (_PyStatus_EXCEPTION(status)) { + Py_ExitStatusException(status); + } + } + else { + /* Global configuration already initialized */ + } -error: - PyConfig_Clear(&config); - Py_ExitStatusException(status); + assert(_Py_path_config.program_full_path != NULL); + assert(_Py_path_config.prefix != NULL); + assert(_Py_path_config.exec_prefix != NULL); + assert(_Py_path_config.module_search_path != NULL); + assert(_Py_path_config.program_name != NULL); + /* home can be NULL */ +#ifdef MS_WINDOWS + assert(_Py_path_config.base_executable != NULL); +#endif } @@ -415,32 +496,26 @@ Py_SetPath(const wchar_t *path) PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - _PyPathConfig new_config; - new_config.program_full_path = _PyMem_RawWcsdup(Py_GetProgramName()); - int alloc_error = (new_config.program_full_path == NULL); - new_config.prefix = _PyMem_RawWcsdup(L""); - alloc_error |= (new_config.prefix == NULL); - new_config.exec_prefix = _PyMem_RawWcsdup(L""); - alloc_error |= (new_config.exec_prefix == NULL); -#ifdef MS_WINDOWS - new_config.dll_path = _Py_GetDLLPath(); - alloc_error |= (new_config.dll_path == NULL); -#endif - new_config.module_search_path = _PyMem_RawWcsdup(path); - alloc_error |= (new_config.module_search_path == NULL); + /* Getting the program full path calls pathconfig_global_init() */ + wchar_t *program_full_path = _PyMem_RawWcsdup(Py_GetProgramFullPath()); - /* steal the home and program_name values (to leave them unchanged) */ - new_config.home = _Py_path_config.home; - _Py_path_config.home = NULL; - new_config.program_name = _Py_path_config.program_name; - _Py_path_config.program_name = NULL; + PyMem_RawFree(_Py_path_config.program_full_path); + PyMem_RawFree(_Py_path_config.prefix); + PyMem_RawFree(_Py_path_config.exec_prefix); + PyMem_RawFree(_Py_path_config.module_search_path); - pathconfig_clear(&_Py_path_config); - _Py_path_config = new_config; + _Py_path_config.program_full_path = program_full_path; + _Py_path_config.prefix = _PyMem_RawWcsdup(L""); + _Py_path_config.exec_prefix = _PyMem_RawWcsdup(L""); + _Py_path_config.module_search_path = _PyMem_RawWcsdup(path); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - if (alloc_error) { + if (_Py_path_config.program_full_path == NULL + || _Py_path_config.prefix == NULL + || _Py_path_config.exec_prefix == NULL + || _Py_path_config.module_search_path == NULL) + { Py_FatalError("Py_SetPath() failed: out of memory"); } } diff --git a/Python/peephole.c b/Python/peephole.c index 1ce3535626e9a6..d859648411fa3f 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -250,12 +250,16 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, lnotab = (unsigned char*)PyBytes_AS_STRING(lnotab_obj); tabsiz = PyBytes_GET_SIZE(lnotab_obj); assert(tabsiz == 0 || Py_REFCNT(lnotab_obj) == 1); - if (memchr(lnotab, 255, tabsiz) != NULL) { - /* 255 value are used for multibyte bytecode instructions */ - goto exitUnchanged; + + /* Don't optimize if lnotab contains instruction pointer delta larger + than +255 (encoded as multiple bytes), just to keep the peephole optimizer + simple. The optimizer leaves line number deltas unchanged. */ + + for (i = 0; i < tabsiz; i += 2) { + if (lnotab[i] == 255) { + goto exitUnchanged; + } } - /* Note: -128 and 127 special values for line number delta are ok, - the peephole optimizer doesn't modify line numbers. */ assert(PyBytes_Check(code)); Py_ssize_t codesize = PyBytes_GET_SIZE(code); @@ -307,13 +311,12 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, } PyObject* cnt = PyList_GET_ITEM(consts, get_arg(codestr, i)); int is_true = PyObject_IsTrue(cnt); + if (is_true == -1) { + goto exitError; + } if (is_true == 1) { fill_nops(codestr, op_start, nexti + 1); cumlc = 0; - } else if (is_true == 0) { - h = get_arg(codestr, nexti) / sizeof(_Py_CODEUNIT); - tgt = find_op(codestr, codelen, h); - fill_nops(codestr, op_start, tgt); } break; diff --git a/Python/preconfig.c b/Python/preconfig.c index 8be6533eace073..89a6227fa67218 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -75,7 +75,7 @@ _Py_SetFileSystemEncoding(const char *encoding, const char *errors) PyStatus _PyArgv_AsWstrList(const _PyArgv *args, PyWideStringList *list) { - PyWideStringList wargv = PyWideStringList_INIT; + PyWideStringList wargv = _PyWideStringList_INIT; if (args->use_bytes_argv) { size_t size = sizeof(wchar_t*) * args->argc; wargv.items = (wchar_t **)PyMem_RawMalloc(size); @@ -274,7 +274,6 @@ _PyPreConfig_InitCompatConfig(PyPreConfig *config) { memset(config, 0, sizeof(*config)); - config->_config_version = _Py_CONFIG_VERSION; config->_config_init = (int)_PyConfig_INIT_COMPAT; config->parse_argv = 0; config->isolated = -1; @@ -336,12 +335,13 @@ PyPreConfig_InitIsolatedConfig(PyPreConfig *config) } -void +PyStatus _PyPreConfig_InitFromPreConfig(PyPreConfig *config, const PyPreConfig *config2) { PyPreConfig_InitPythonConfig(config); preconfig_copy(config, config2); + return _PyStatus_OK(); } @@ -360,6 +360,7 @@ _PyPreConfig_InitFromConfig(PyPreConfig *preconfig, const PyConfig *config) default: _PyPreConfig_InitCompatConfig(preconfig); } + _PyPreConfig_GetConfig(preconfig, config); } @@ -367,7 +368,6 @@ _PyPreConfig_InitFromConfig(PyPreConfig *preconfig, const PyConfig *config) static void preconfig_copy(PyPreConfig *config, const PyPreConfig *config2) { - assert(config2->_config_version == _Py_CONFIG_VERSION); #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR COPY_ATTR(_config_init); @@ -801,7 +801,11 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) /* Save the config to be able to restore it if encodings change */ PyPreConfig save_config; - _PyPreConfig_InitFromPreConfig(&save_config, config); + + status = _PyPreConfig_InitFromPreConfig(&save_config, config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } /* Set LC_CTYPE to the user preferred locale */ if (config->configure_locale) { @@ -923,7 +927,11 @@ PyStatus _PyPreConfig_Write(const PyPreConfig *src_config) { PyPreConfig config; - _PyPreConfig_InitFromPreConfig(&config, src_config); + + PyStatus status = _PyPreConfig_InitFromPreConfig(&config, src_config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } if (_PyRuntime.core_initialized) { /* bpo-34008: Calling this functions after Py_Initialize() ignores diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 751c4d6d1d631c..feb92852392401 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -472,7 +472,7 @@ pyinit_core_reconfigure(_PyRuntimeState *runtime, config = &interp->config; if (config->_install_importlib) { - status = _PyConfig_SetPathConfig(config); + status = _PyConfig_WritePathConfig(config); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -623,6 +623,8 @@ pycore_init_builtins(PyInterpreterState *interp) static PyStatus pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod) { + const PyConfig *config = &interp->config; + PyStatus status = _PyImport_Init(interp); if (_PyStatus_EXCEPTION(status)) { return status; @@ -638,15 +640,15 @@ pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod) return _PyStatus_ERR("can't initialize warnings"); } - if (interp->config._install_importlib) { - status = _PyConfig_SetPathConfig(&interp->config); + if (config->_install_importlib) { + status = _PyConfig_WritePathConfig(config); if (_PyStatus_EXCEPTION(status)) { return status; } } /* This call sets up builtin and frozen import support */ - if (interp->config._install_importlib) { + if (config->_install_importlib) { status = init_importlib(interp, sysmod); if (_PyStatus_EXCEPTION(status)) { return status; @@ -719,13 +721,21 @@ _Py_PreInitializeFromPyArgv(const PyPreConfig *src_config, const _PyArgv *args) } _PyRuntimeState *runtime = &_PyRuntime; - if (runtime->pre_initialized) { + if (runtime->preinitialized) { /* If it's already configured: ignored the new configuration */ return _PyStatus_OK(); } + /* Note: preinitialized remains 1 on error, it is only set to 0 + at exit on success. */ + runtime->preinitializing = 1; + PyPreConfig config; - _PyPreConfig_InitFromPreConfig(&config, src_config); + + status = _PyPreConfig_InitFromPreConfig(&config, src_config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } status = _PyPreConfig_Read(&config, args); if (_PyStatus_EXCEPTION(status)) { @@ -737,7 +747,8 @@ _Py_PreInitializeFromPyArgv(const PyPreConfig *src_config, const _PyArgv *args) return status; } - runtime->pre_initialized = 1; + runtime->preinitializing = 0; + runtime->preinitialized = 1; return _PyStatus_OK(); } @@ -777,12 +788,13 @@ _Py_PreInitializeFromConfig(const PyConfig *config, } _PyRuntimeState *runtime = &_PyRuntime; - if (runtime->pre_initialized) { + if (runtime->preinitialized) { /* Already initialized: do nothing */ return _PyStatus_OK(); } PyPreConfig preconfig; + _PyPreConfig_InitFromConfig(&preconfig, config); if (!config->parse_argv) { @@ -934,7 +946,8 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) return status; } - status = _PyUnicode_InitEncodings(interp); + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + status = _PyUnicode_InitEncodings(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1054,6 +1067,7 @@ Py_InitializeEx(int install_sigs) PyConfig config; _PyConfig_InitCompatConfig(&config); + config.install_signal_handlers = install_sigs; status = Py_InitializeFromConfig(&config); @@ -1501,7 +1515,7 @@ new_interpreter(PyThreadState **tstate_p) return status; } - status = _PyUnicode_InitEncodings(interp); + status = _PyUnicode_InitEncodings(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1961,13 +1975,14 @@ init_sys_streams(PyInterpreterState *interp) static void -_Py_FatalError_DumpTracebacks(int fd) +_Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp, + PyThreadState *tstate) { fputc('\n', stderr); fflush(stderr); /* display the current Python stack */ - _Py_DumpTracebackThreads(fd, NULL, NULL); + _Py_DumpTracebackThreads(fd, interp, tstate); } /* Print the current exception (if an exception is set) with its traceback, @@ -2062,10 +2077,39 @@ fatal_output_debug(const char *msg) } #endif + +static void +fatal_error_dump_runtime(FILE *stream, _PyRuntimeState *runtime) +{ + fprintf(stream, "Python runtime state: "); + if (runtime->finalizing) { + fprintf(stream, "finalizing (tstate=%p)", runtime->finalizing); + } + else if (runtime->initialized) { + fprintf(stream, "initialized"); + } + else if (runtime->core_initialized) { + fprintf(stream, "core initialized"); + } + else if (runtime->preinitialized) { + fprintf(stream, "preinitialized"); + } + else if (runtime->preinitializing) { + fprintf(stream, "preinitializing"); + } + else { + fprintf(stream, "unknown"); + } + fprintf(stream, "\n"); + fflush(stream); +} + + static void _Py_NO_RETURN fatal_error(const char *prefix, const char *msg, int status) { - const int fd = fileno(stderr); + FILE *stream = stderr; + const int fd = fileno(stream); static int reentrant = 0; if (reentrant) { @@ -2075,45 +2119,48 @@ fatal_error(const char *prefix, const char *msg, int status) } reentrant = 1; - fprintf(stderr, "Fatal Python error: "); + fprintf(stream, "Fatal Python error: "); if (prefix) { - fputs(prefix, stderr); - fputs(": ", stderr); + fputs(prefix, stream); + fputs(": ", stream); } if (msg) { - fputs(msg, stderr); + fputs(msg, stream); } else { - fprintf(stderr, ""); + fprintf(stream, ""); } - fputs("\n", stderr); - fflush(stderr); /* it helps in Windows debug build */ + fputs("\n", stream); + fflush(stream); /* it helps in Windows debug build */ - /* Check if the current thread has a Python thread state - and holds the GIL */ - PyThreadState *tss_tstate = PyGILState_GetThisThreadState(); - if (tss_tstate != NULL) { - PyThreadState *tstate = _PyThreadState_GET(); - if (tss_tstate != tstate) { - /* The Python thread does not hold the GIL */ - tss_tstate = NULL; - } - } - else { - /* Py_FatalError() has been called from a C thread - which has no Python thread state. */ + _PyRuntimeState *runtime = &_PyRuntime; + fatal_error_dump_runtime(stream, runtime); + + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyInterpreterState *interp = NULL; + if (tstate != NULL) { + interp = tstate->interp; } - int has_tstate_and_gil = (tss_tstate != NULL); + /* Check if the current thread has a Python thread state + and holds the GIL. + + tss_tstate is NULL if Py_FatalError() is called from a C thread which + has no Python thread state. + + tss_tstate != tstate if the current Python thread does not hold the GIL. + */ + PyThreadState *tss_tstate = PyGILState_GetThisThreadState(); + int has_tstate_and_gil = (tss_tstate != NULL && tss_tstate == tstate); if (has_tstate_and_gil) { /* If an exception is set, print the exception with its traceback */ if (!_Py_FatalError_PrintExc(fd)) { /* No exception is set, or an exception is set without traceback */ - _Py_FatalError_DumpTracebacks(fd); + _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate); } } else { - _Py_FatalError_DumpTracebacks(fd); + _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate); } /* The main purpose of faulthandler is to display the traceback. diff --git a/Python/pystate.c b/Python/pystate.c index 833e0fb30dcb26..aba673c00a4322 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -60,6 +60,7 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) _PyGC_Initialize(&runtime->gc); _PyEval_Initialize(&runtime->ceval); + PyPreConfig_InitPythonConfig(&runtime->preconfig); runtime->gilstate.check_enabled = 1; @@ -205,14 +206,7 @@ PyInterpreterState_New(void) interp->id_refcount = -1; interp->check_interval = 100; - PyStatus status = PyConfig_InitPythonConfig(&interp->config); - if (_PyStatus_EXCEPTION(status)) { - /* Don't report status to caller: PyConfig_InitPythonConfig() - can only fail with a memory allocation error. */ - PyConfig_Clear(&interp->config); - PyMem_RawFree(interp); - return NULL; - } + PyConfig_InitPythonConfig(&interp->config); interp->eval_frame = _PyEval_EvalFrameDefault; #ifdef HAVE_DLOPEN @@ -685,7 +679,7 @@ _PyState_AddModule(PyObject* module, struct PyModuleDef* def) if (!state->modules_by_index) return -1; } - while(PyList_GET_SIZE(state->modules_by_index) <= def->m_base.m_index) + while (PyList_GET_SIZE(state->modules_by_index) <= def->m_base.m_index) if (PyList_Append(state->modules_by_index, Py_None) < 0) return -1; Py_INCREF(module); @@ -703,13 +697,11 @@ PyState_AddModule(PyObject* module, struct PyModuleDef* def) return -1; } index = def->m_base.m_index; - if (state->modules_by_index) { - if(PyList_GET_SIZE(state->modules_by_index) >= index) { - if(module == PyList_GET_ITEM(state->modules_by_index, index)) { - Py_FatalError("PyState_AddModule: Module already added!"); - return -1; - } - } + if (state->modules_by_index && + index < PyList_GET_SIZE(state->modules_by_index) && + module == PyList_GET_ITEM(state->modules_by_index, index)) { + Py_FatalError("PyState_AddModule: Module already added!"); + return -1; } return _PyState_AddModule(module, def); } @@ -730,7 +722,7 @@ PyState_RemoveModule(struct PyModuleDef* def) return -1; } if (state->modules_by_index == NULL) { - Py_FatalError("PyState_RemoveModule: Interpreters module-list not acessible."); + Py_FatalError("PyState_RemoveModule: Interpreters module-list not accessible."); return -1; } if (index > PyList_GET_SIZE(state->modules_by_index)) { @@ -885,7 +877,7 @@ PyThreadState_DeleteCurrent() * Note that, if there is a current thread state, it *must* be the one * passed as argument. Also, this won't touch any other interpreters * than the current one, since we don't know which thread state should - * be kept in those other interpreteres. + * be kept in those other interpreters. */ void _PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) diff --git a/Python/pystrhex.c b/Python/pystrhex.c index 5dc7c9613796e0..9d34f71a2e9cf3 100644 --- a/Python/pystrhex.c +++ b/Python/pystrhex.c @@ -57,7 +57,7 @@ static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, } resultlen += arglen * 2; - if (abs_bytes_per_sep >= arglen) { + if ((size_t)abs_bytes_per_sep >= (size_t)arglen) { bytes_per_sep_group = 0; abs_bytes_per_sep = 0; } diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 784c15bb4b22ce..f1d946a0b0f83d 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -91,7 +91,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * { PyObject *filename, *v; int ret, err; - PyCompilerFlags local_flags; + PyCompilerFlags local_flags = _PyCompilerFlags_INIT; int nomem_count = 0; #ifdef Py_REF_DEBUG int show_ref_count = _PyInterpreterState_Get()->config.show_ref_count; @@ -105,8 +105,6 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * if (flags == NULL) { flags = &local_flags; - local_flags.cf_flags = 0; - local_flags.cf_feature_version = PY_MINOR_VERSION; } v = _PySys_GetObjectId(&PyId_ps1); if (v == NULL) { @@ -799,7 +797,7 @@ print_exception(PyObject *f, PyObject *value) Py_DECREF(value); value = message; - line = PyUnicode_FromFormat(" File \"%U\", line %d\n", + line = PyUnicode_FromFormat(" File \"%S\", line %d\n", filename, lineno); Py_DECREF(filename); if (line != NULL) { @@ -1283,10 +1281,7 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp struct symtable * Py_SymtableStringObject(const char *str, PyObject *filename, int start) { - PyCompilerFlags flags; - - flags.cf_flags = 0; - flags.cf_feature_version = PY_MINOR_VERSION; + PyCompilerFlags flags = _PyCompilerFlags_INIT; return _Py_SymtableStringObjectFlags(str, filename, start, &flags); } @@ -1331,7 +1326,7 @@ PyParser_ASTFromStringObject(const char *s, PyObject *filename, int start, PyCompilerFlags *flags, PyArena *arena) { mod_ty mod; - PyCompilerFlags localflags; + PyCompilerFlags localflags = _PyCompilerFlags_INIT; perrdetail err; int iflags = PARSER_FLAGS(flags); if (flags && flags->cf_feature_version < 7) @@ -1341,8 +1336,6 @@ PyParser_ASTFromStringObject(const char *s, PyObject *filename, int start, &_PyParser_Grammar, start, &err, &iflags); if (flags == NULL) { - localflags.cf_flags = 0; - localflags.cf_feature_version = PY_MINOR_VERSION; flags = &localflags; } if (n) { @@ -1379,7 +1372,7 @@ PyParser_ASTFromFileObject(FILE *fp, PyObject *filename, const char* enc, PyArena *arena) { mod_ty mod; - PyCompilerFlags localflags; + PyCompilerFlags localflags = _PyCompilerFlags_INIT; perrdetail err; int iflags = PARSER_FLAGS(flags); @@ -1387,8 +1380,6 @@ PyParser_ASTFromFileObject(FILE *fp, PyObject *filename, const char* enc, &_PyParser_Grammar, start, ps1, ps2, &err, &iflags); if (flags == NULL) { - localflags.cf_flags = 0; - localflags.cf_feature_version = PY_MINOR_VERSION; flags = &localflags; } if (n) { diff --git a/Python/symtable.c b/Python/symtable.c index 668cc21b2df987..b8713588b9a914 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -32,7 +32,16 @@ #define IMPORT_STAR_WARNING "import * only allowed at module level" #define NAMED_EXPR_COMP_IN_CLASS \ -"named expression within a comprehension cannot be used in a class body" +"assignment expression within a comprehension cannot be used in a class body" + +#define NAMED_EXPR_COMP_CONFLICT \ +"assignment expression cannot rebind comprehension iteration variable '%U'" + +#define NAMED_EXPR_COMP_INNER_LOOP_CONFLICT \ +"comprehension inner loop cannot rebind assignment expression target '%U'" + +#define NAMED_EXPR_COMP_ITER_EXPR \ +"assignment expression cannot be used in a comprehension iterable expression" static PySTEntryObject * ste_new(struct symtable *st, identifier name, _Py_block_ty block, @@ -81,6 +90,8 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_comprehension = 0; ste->ste_returns_value = 0; ste->ste_needs_class_closure = 0; + ste->ste_comp_iter_target = 0; + ste->ste_comp_iter_expr = 0; ste->ste_symbols = PyDict_New(); ste->ste_varnames = PyList_New(0); @@ -255,6 +266,7 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) int i; PyThreadState *tstate; int recursion_limit = Py_GetRecursionLimit(); + int starting_recursion_depth; if (st == NULL) return NULL; @@ -273,8 +285,9 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) return NULL; } /* Be careful here to prevent overflow. */ - st->recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? + starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? tstate->recursion_depth * COMPILER_STACK_FRAME_SCALE : tstate->recursion_depth; + 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; @@ -318,6 +331,14 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) PySymtable_Free(st); return NULL; } + /* Check that the recursion depth counting balanced correctly */ + if (st->recursion_depth != starting_recursion_depth) { + PyErr_Format(PyExc_SystemError, + "symtable analysis recursion depth mismatch (before=%d, after=%d)", + starting_recursion_depth, st->recursion_depth); + PySymtable_Free(st); + return NULL; + } /* Make the second symbol analysis pass */ if (symtable_analyze(st)) return st; @@ -373,14 +394,21 @@ PySymtable_Lookup(struct symtable *st, void *key) return (PySTEntryObject *)v; } -int -PyST_GetScope(PySTEntryObject *ste, PyObject *name) +static long +_PyST_GetSymbol(PySTEntryObject *ste, PyObject *name) { PyObject *v = PyDict_GetItem(ste->ste_symbols, name); if (!v) return 0; assert(PyLong_Check(v)); - return (PyLong_AS_LONG(v) >> SCOPE_OFFSET) & SCOPE_MASK; + return PyLong_AS_LONG(v); +} + +int +PyST_GetScope(PySTEntryObject *ste, PyObject *name) +{ + long symbol = _PyST_GetSymbol(ste, name); + return (symbol >> SCOPE_OFFSET) & SCOPE_MASK; } static int @@ -955,6 +983,13 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block, return 0; } prev = st->st_cur; + /* bpo-37757: For now, disallow *all* assignment expressions in the + * outermost iterator expression of a comprehension, even those inside + * a nested comprehension or a lambda expression. + */ + if (prev) { + ste->ste_comp_iter_expr = prev->ste_comp_iter_expr; + } /* The entry is owned by the stack. Borrow it for st_cur. */ Py_DECREF(ste); st->st_cur = ste; @@ -971,15 +1006,12 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block, static long symtable_lookup(struct symtable *st, PyObject *name) { - PyObject *o; PyObject *mangled = _Py_Mangle(st->st_private, name); if (!mangled) return 0; - o = PyDict_GetItem(st->st_cur->ste_symbols, mangled); + long ret = _PyST_GetSymbol(st->st_cur, mangled); Py_DECREF(mangled); - if (!o) - return 0; - return PyLong_AsLong(o); + return ret; } static int @@ -1012,6 +1044,22 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s else { val = flag; } + if (ste->ste_comp_iter_target) { + /* This name is an iteration variable in a comprehension, + * so check for a binding conflict with any named expressions. + * Otherwise, mark it as an iteration variable so subsequent + * named expressions can check for conflicts. + */ + if (val & (DEF_GLOBAL | DEF_NONLOCAL)) { + PyErr_Format(PyExc_SyntaxError, + NAMED_EXPR_COMP_INNER_LOOP_CONFLICT, name); + PyErr_SyntaxLocationObject(st->st_filename, + ste->ste_lineno, + ste->ste_col_offset + 1); + goto error; + } + val |= DEF_COMP_ITER; + } o = PyLong_FromLong(val); if (o == NULL) goto error; @@ -1392,7 +1440,9 @@ static int symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) { assert(st->st_stack); + assert(e->kind == Name_kind); + PyObject *target_name = e->v.Name.id; Py_ssize_t i, size; struct _symtable_entry *ste; size = PyList_GET_SIZE(st->st_stack); @@ -1402,32 +1452,48 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) for (i = size - 1; i >= 0; i--) { ste = (struct _symtable_entry *) PyList_GET_ITEM(st->st_stack, i); - /* If our current entry is a comprehension, skip it */ + /* If we find a comprehension scope, check for a target + * binding conflict with iteration variables, otherwise skip it + */ if (ste->ste_comprehension) { + long target_in_scope = _PyST_GetSymbol(ste, target_name); + if (target_in_scope & DEF_COMP_ITER) { + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name); + PyErr_SyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset); + VISIT_QUIT(st, 0); + } continue; } - /* If we find a FunctionBlock entry, add as NONLOCAL/LOCAL */ + /* If we find a FunctionBlock entry, add as GLOBAL/LOCAL or NONLOCAL/LOCAL */ if (ste->ste_type == FunctionBlock) { - if (!symtable_add_def(st, e->v.Name.id, DEF_NONLOCAL)) - VISIT_QUIT(st, 0); - if (!symtable_record_directive(st, e->v.Name.id, e->lineno, e->col_offset)) + long target_in_scope = _PyST_GetSymbol(ste, target_name); + if (target_in_scope & DEF_GLOBAL) { + if (!symtable_add_def(st, target_name, DEF_GLOBAL)) + VISIT_QUIT(st, 0); + } else { + if (!symtable_add_def(st, target_name, DEF_NONLOCAL)) + VISIT_QUIT(st, 0); + } + if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset)) VISIT_QUIT(st, 0); - return symtable_add_def_helper(st, e->v.Name.id, DEF_LOCAL, ste); + return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste); } /* If we find a ModuleBlock entry, add as GLOBAL */ if (ste->ste_type == ModuleBlock) { - if (!symtable_add_def(st, e->v.Name.id, DEF_GLOBAL)) + if (!symtable_add_def(st, target_name, DEF_GLOBAL)) VISIT_QUIT(st, 0); - if (!symtable_record_directive(st, e->v.Name.id, e->lineno, e->col_offset)) + if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset)) VISIT_QUIT(st, 0); - return symtable_add_def_helper(st, e->v.Name.id, DEF_GLOBAL, ste); + return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste); } /* Disallow usage in ClassBlock */ if (ste->ste_type == ClassBlock) { - PyErr_Format(PyExc_TargetScopeError, NAMED_EXPR_COMP_IN_CLASS, e->v.Name.id); + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_CLASS); PyErr_SyntaxLocationObject(st->st_filename, e->lineno, e->col_offset); @@ -1442,6 +1508,27 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) return 0; } +static int +symtable_handle_namedexpr(struct symtable *st, expr_ty e) +{ + if (st->st_cur->ste_comp_iter_expr > 0) { + /* Assignment isn't allowed in a comprehension iterable expression */ + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_ITER_EXPR); + PyErr_SyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset); + return 0; + } + if (st->st_cur->ste_comprehension) { + /* Inside a comprehension body, so find the right target scope */ + if (!symtable_extend_namedexpr_scope(st, e->v.NamedExpr.target)) + return 0; + } + VISIT(st, expr, e->v.NamedExpr.value); + VISIT(st, expr, e->v.NamedExpr.target); + return 1; +} + static int symtable_visit_expr(struct symtable *st, expr_ty e) { @@ -1452,12 +1539,8 @@ symtable_visit_expr(struct symtable *st, expr_ty e) } switch (e->kind) { case NamedExpr_kind: - if (st->st_cur->ste_comprehension) { - if (!symtable_extend_namedexpr_scope(st, e->v.NamedExpr.target)) - VISIT_QUIT(st, 0); - } - VISIT(st, expr, e->v.NamedExpr.value); - VISIT(st, expr, e->v.NamedExpr.target); + if(!symtable_handle_namedexpr(st, e)) + VISIT_QUIT(st, 0); break; case BoolOp_kind: VISIT_SEQ(st, expr, e->v.BoolOp.values); @@ -1739,8 +1822,12 @@ symtable_visit_alias(struct symtable *st, alias_ty a) static int symtable_visit_comprehension(struct symtable *st, comprehension_ty lc) { + st->st_cur->ste_comp_iter_target = 1; VISIT(st, expr, lc->target); + st->st_cur->ste_comp_iter_target = 0; + st->st_cur->ste_comp_iter_expr++; VISIT(st, expr, lc->iter); + st->st_cur->ste_comp_iter_expr--; VISIT_SEQ(st, expr, lc->ifs); if (lc->is_async) { st->st_cur->ste_coroutine = 1; @@ -1788,7 +1875,9 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, comprehension_ty outermost = ((comprehension_ty) asdl_seq_GET(generators, 0)); /* Outermost iterator is evaluated in current scope */ + st->st_cur->ste_comp_iter_expr++; VISIT(st, expr, outermost->iter); + st->st_cur->ste_comp_iter_expr--; /* Create comprehension scope for the rest */ if (!scope_name || !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, @@ -1805,7 +1894,11 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, symtable_exit_block(st, (void *)e); return 0; } + /* Visit iteration variable target, and mark them as such */ + st->st_cur->ste_comp_iter_target = 1; VISIT(st, expr, outermost->target); + st->st_cur->ste_comp_iter_target = 0; + /* Visit the rest of the comprehension body */ VISIT_SEQ(st, expr, outermost->ifs); VISIT_SEQ_TAIL(st, comprehension, generators, 1); if (value) diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 12b1bd7711d5b8..5b0fb813b4566b 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -160,6 +160,7 @@ PySys_Audit(const char *event, const char *argFormat, ...) va_list args; va_start(args, argFormat); eventArgs = Py_VaBuildValue(argFormat, args); + va_end(args); if (eventArgs && !PyTuple_Check(eventArgs)) { PyObject *argTuple = PyTuple_Pack(1, eventArgs); Py_DECREF(eventArgs); @@ -200,16 +201,12 @@ PySys_Audit(const char *event, const char *argFormat, ...) ts->tracing++; ts->use_tracing = 0; while ((hook = PyIter_Next(hooks)) != NULL) { + _Py_IDENTIFIER(__cantrace__); PyObject *o; - int canTrace = -1; - o = PyObject_GetAttrString(hook, "__cantrace__"); + int canTrace = _PyObject_LookupAttrId(hook, &PyId___cantrace__, &o); if (o) { canTrace = PyObject_IsTrue(o); Py_DECREF(o); - } else if (PyErr_Occurred() && - PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - canTrace = 0; } if (canTrace < 0) { break; @@ -537,7 +534,10 @@ sys_displayhook_unencodable(PyObject *outf, PyObject *o) if (encoded == NULL) goto error; - buffer = _PyObject_GetAttrId(outf, &PyId_buffer); + if (_PyObject_LookupAttrId(outf, &PyId_buffer, &buffer) < 0) { + Py_DECREF(encoded); + goto error; + } if (buffer) { result = _PyObject_CallMethodIdObjArgs(buffer, &PyId_write, encoded, NULL); Py_DECREF(buffer); @@ -547,7 +547,6 @@ sys_displayhook_unencodable(PyObject *outf, PyObject *o) Py_DECREF(result); } else { - PyErr_Clear(); escaped_str = PyUnicode_FromEncodedObject(encoded, stdout_encoding_str, "strict"); @@ -706,7 +705,7 @@ sys_unraisablehook(PyObject *module, PyObject *unraisable) /*[clinic input] sys.exit - status: object = NULL + status: object = None / Exit the interpreter by raising SystemExit(status). @@ -719,7 +718,7 @@ exit status will be one (i.e., failure). static PyObject * sys_exit_impl(PyObject *module, PyObject *status) -/*[clinic end generated code: output=13870986c1ab2ec0 input=a737351f86685e9c]*/ +/*[clinic end generated code: output=13870986c1ab2ec0 input=b86ca9497baa94f2]*/ { /* Raise SystemExit so callers may catch it or clean up. */ PyErr_SetObject(PyExc_SystemExit, status); @@ -1163,7 +1162,7 @@ static PyTypeObject AsyncGenHooksType; PyDoc_STRVAR(asyncgen_hooks_doc, "asyncgen_hooks\n\ \n\ -A struct sequence providing information about asynhronous\n\ +A named tuple providing information about asynchronous\n\ generators hooks. The attributes are read only."); static PyStructSequence_Field asyncgen_hooks_fields[] = { @@ -1271,7 +1270,7 @@ static PyTypeObject Hash_InfoType; PyDoc_STRVAR(hash_info_doc, "hash_info\n\ \n\ -A struct sequence providing parameters used for computing\n\ +A named tuple providing parameters used for computing\n\ hashes. The attributes are read only."); static PyStructSequence_Field hash_info_fields[] = { @@ -2070,37 +2069,43 @@ _clear_preinit_entries(_Py_PreInitEntry *optionlist) PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } -static void -_clear_all_preinit_options(void) + +PyStatus +_PySys_ReadPreinitWarnOptions(PyWideStringList *options) { + PyStatus status; + _Py_PreInitEntry entry; + + for (entry = _preinit_warnoptions; entry != NULL; entry = entry->next) { + status = PyWideStringList_Append(options, entry->value); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + _clear_preinit_entries(&_preinit_warnoptions); - _clear_preinit_entries(&_preinit_xoptions); + return _PyStatus_OK(); } -static int -_PySys_ReadPreInitOptions(void) + +PyStatus +_PySys_ReadPreinitXOptions(PyConfig *config) { - /* Rerun the add commands with the actual sys module available */ - PyThreadState *tstate = _PyThreadState_GET(); - if (tstate == NULL) { - /* Still don't have a thread state, so something is wrong! */ - return -1; - } - _Py_PreInitEntry entry = _preinit_warnoptions; - while (entry != NULL) { - PySys_AddWarnOption(entry->value); - entry = entry->next; - } - entry = _preinit_xoptions; - while (entry != NULL) { - PySys_AddXOption(entry->value); - entry = entry->next; + PyStatus status; + _Py_PreInitEntry entry; + + for (entry = _preinit_xoptions; entry != NULL; entry = entry->next) { + status = PyWideStringList_Append(&config->xoptions, entry->value); + if (_PyStatus_EXCEPTION(status)) { + return status; + } } - _clear_all_preinit_options(); - return 0; + _clear_preinit_entries(&_preinit_xoptions); + return _PyStatus_OK(); } + static PyObject * get_warnoptions(void) { @@ -2264,9 +2269,7 @@ PySys_AddXOption(const wchar_t *s) } if (_PySys_AddXOptionWithError(s) < 0) { /* No return value, therefore clear error state if possible */ - if (_PyThreadState_UncheckedGet()) { - PyErr_Clear(); - } + PyErr_Clear(); } } @@ -2318,17 +2321,17 @@ builtin_module_names -- tuple of module names built into this interpreter\n\ copyright -- copyright notice pertaining to this interpreter\n\ exec_prefix -- prefix used to find the machine-specific Python library\n\ executable -- absolute path of the executable binary of the Python interpreter\n\ -float_info -- a struct sequence with information about the float implementation.\n\ +float_info -- a named tuple with information about the float implementation.\n\ float_repr_style -- string indicating the style of repr() output for floats\n\ -hash_info -- a struct sequence with information about the hash algorithm.\n\ +hash_info -- a named tuple with information about the hash algorithm.\n\ hexversion -- version information encoded as a single integer\n\ implementation -- Python implementation information.\n\ -int_info -- a struct sequence with information about the int implementation.\n\ +int_info -- a named tuple with information about the int implementation.\n\ maxsize -- the largest supported length of containers.\n\ maxunicode -- the value of the largest Unicode code point\n\ platform -- platform identifier\n\ prefix -- prefix used to find the Python library\n\ -thread_info -- a struct sequence with information about the thread implementation.\n\ +thread_info -- a named tuple with information about the thread implementation.\n\ version -- the version of this interpreter as a string\n\ version_info -- version information as a named tuple\n\ " @@ -2878,6 +2881,7 @@ _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) COPY_LIST("path", config->module_search_paths); SET_SYS_FROM_WSTR("executable", config->executable); + SET_SYS_FROM_WSTR("_base_executable", config->base_executable); SET_SYS_FROM_WSTR("prefix", config->prefix); SET_SYS_FROM_WSTR("base_prefix", config->base_prefix); SET_SYS_FROM_WSTR("exec_prefix", config->exec_prefix); @@ -2924,13 +2928,9 @@ _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) if (get_xoptions() == NULL) return -1; - /* Transfer any sys.warnoptions and sys._xoptions set directly - * by an embedding application from the linked list to the module. */ - if (_PySys_ReadPreInitOptions() != 0) - return -1; - if (PyErr_Occurred()) return -1; + return 0; err_occurred: @@ -3078,9 +3078,10 @@ make_sys_argv(int argc, wchar_t * const * argv) void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) { + wchar_t* empty_argv[1] = {L""}; + if (argc < 1 || argv == NULL) { /* Ensure at least one (empty) argument is seen */ - wchar_t* empty_argv[1] = {L""}; argv = empty_argv; argc = 1; } diff --git a/Python/thread.c b/Python/thread.c index c5364f91948f86..c36ce6ff9835d8 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -147,7 +147,7 @@ PyThread_tss_is_created(Py_tss_t *key) PyDoc_STRVAR(threadinfo__doc__, "sys.thread_info\n\ \n\ -A struct sequence holding information about the thread implementation."); +A named tuple holding information about the thread implementation."); static PyStructSequence_Field threadinfo_fields[] = { {"name", "name of the thread implementation"}, diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 740b521b944621..5678b05ced3698 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -18,6 +18,10 @@ # include /* pthread_getthreadid_np() */ #elif defined(__OpenBSD__) # include /* getthrid() */ +#elif defined(_AIX) +# include /* thread_self() */ +#elif defined(__NetBSD__) +# include /* _lwp_self() */ #endif /* The POSIX spec requires that use of pthread_attr_setstacksize @@ -36,12 +40,17 @@ */ #if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 #undef THREAD_STACK_SIZE -#define THREAD_STACK_SIZE 0x500000 +/* Note: This matches the value of -Wl,-stack_size in configure.ac */ +#define THREAD_STACK_SIZE 0x1000000 #endif #if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 #undef THREAD_STACK_SIZE #define THREAD_STACK_SIZE 0x400000 #endif +#if defined(_AIX) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 +#undef THREAD_STACK_SIZE +#define THREAD_STACK_SIZE 0x200000 +#endif /* for safety, ensure a viable minimum stacksize */ #define THREAD_STACK_MIN 0x8000 /* 32 KiB */ #else /* !_POSIX_THREAD_ATTR_STACKSIZE */ @@ -328,6 +337,12 @@ PyThread_get_thread_native_id(void) #elif defined(__OpenBSD__) pid_t native_id; native_id = getthrid(); +#elif defined(_AIX) + tid_t native_id; + native_id = thread_self(); +#elif defined(__NetBSD__) + lwpid_t native_id; + native_id = _lwp_self(); #endif return (unsigned long) native_id; } diff --git a/Python/traceback.c b/Python/traceback.c index 0463eb6d8c98e7..8e2f15e85d6b5d 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -797,12 +797,15 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header) PyFrameObject *frame; unsigned int depth; - if (write_header) + if (write_header) { PUTS(fd, "Stack (most recent call first):\n"); + } frame = _PyThreadState_GetFrame(tstate); - if (frame == NULL) + if (frame == NULL) { + PUTS(fd, "\n"); return; + } depth = 0; while (frame != NULL) { @@ -870,9 +873,9 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, Python thread state of the current thread. PyThreadState_Get() doesn't give the state of the thread that caused - the fault if the thread released the GIL, and so this function - cannot be used. Read the thread specific storage (TSS) instead: call - PyGILState_GetThisThreadState(). */ + the fault if the thread released the GIL, and so + _PyThreadState_GET() cannot be used. Read the thread specific + storage (TSS) instead: call PyGILState_GetThisThreadState(). */ current_tstate = PyGILState_GetThisThreadState(); } diff --git a/README.rst b/README.rst index b0a0ce7ec287b6..76d70b3e2d6d13 100644 --- a/README.rst +++ b/README.rst @@ -1,21 +1,17 @@ -This is Python version 3.8.0 beta 1 -=================================== +This is Python version 3.8.0 +============================ -.. image:: https://travis-ci.org/python/cpython.svg?branch=master +.. image:: https://travis-ci.org/python/cpython.svg?branch=3.8 :alt: CPython build status on Travis CI - :target: https://travis-ci.org/python/cpython + :target: https://travis-ci.org/python/cpython/branches -.. image:: https://ci.appveyor.com/api/projects/status/4mew1a93xdkbf5ua/branch/master?svg=true - :alt: CPython build status on Appveyor - :target: https://ci.appveyor.com/project/python/cpython/branch/master - -.. image:: https://dev.azure.com/python/cpython/_apis/build/status/Azure%20Pipelines%20CI?branchName=master +.. image:: https://dev.azure.com/python/cpython/_apis/build/status/Azure%20Pipelines%20CI?branchName=3.8 :alt: CPython build status on Azure DevOps - :target: https://dev.azure.com/python/cpython/_build/latest?definitionId=4&branchName=master + :target: https://dev.azure.com/python/cpython/_build/latest?definitionId=4&branchName=3.8 -.. image:: https://codecov.io/gh/python/cpython/branch/master/graph/badge.svg +.. image:: https://codecov.io/gh/python/cpython/branch/3.8/graph/badge.svg :alt: CPython code coverage on Codecov - :target: https://codecov.io/gh/python/cpython + :target: https://codecov.io/gh/python/cpython/branch/3.8 .. image:: https://img.shields.io/badge/zulip-join_chat-brightgreen.svg :alt: Python Zulip chat @@ -66,21 +62,23 @@ On Unix, Linux, BSD, macOS, and Cygwin:: This will install Python as ``python3``. You can pass many options to the configure script; run ``./configure --help`` -to find out more. On macOS and Cygwin, the executable is called ``python.exe``; -elsewhere it's just ``python``. +to find out more. On macOS case-insensitive file systems and on Cygwin, +the executable is called ``python.exe``; elsewhere it's just ``python``. -If you are running on macOS with the latest updates installed, make sure to install -OpenSSL or some other SSL software along with Homebrew or another package manager. -If issues persist, see https://devguide.python.org/setup/#macos-and-os-x for more -information. +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 `_ +section of the `Developer Guide`_ for current detailed information on +dependencies for various Linux distributions and macOS. -On macOS, if you have configured Python with ``--enable-framework``, you -should use ``make frameworkinstall`` to do the installation. Note that this -installs the Python executable in a place that is not normally on your PATH, -you may want to set up a symlink in ``/usr/local/bin``. +On macOS, there are additional configure and build options related +to macOS framework and universal builds. Refer to `Mac/README.rst +`_. On Windows, see `PCbuild/readme.txt -`_. +`_. If you wish, you can create a subdirectory and invoke configure from there. For example:: @@ -100,7 +98,6 @@ Profile Guided Optimization (PGO) and may be used to auto-enable Link Time Optimization (LTO) on some platforms. For more details, see the sections below. - Profile Guided Optimization ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -142,9 +139,9 @@ What's New We have a comprehensive overview of the changes in the `What's New in Python 3.8 `_ 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 -`_. +`_. If you want to install multiple versions of Python, see the section below entitled "Installing multiple versions". @@ -162,7 +159,7 @@ is primarily for documentation authors, translators, and people with special formatting requirements. For information about building Python's documentation, refer to `Doc/README.rst -`_. +`_. Converting From Python 2.x to 3.x diff --git a/Tools/buildbot/remoteDeploy.bat b/Tools/buildbot/remoteDeploy.bat new file mode 100644 index 00000000000000..6b86e1e59b077d --- /dev/null +++ b/Tools/buildbot/remoteDeploy.bat @@ -0,0 +1,53 @@ +@echo off +rem Used by the buildbot "remotedeploy" step. +setlocal + +set PATH=%PATH%;%SystemRoot%\SysNative\OpenSSH;%SystemRoot%\System32\OpenSSH +set here=%~dp0 +set arm32_ssh= + +:CheckOpts +if "%1"=="-arm32" (set arm32_ssh=true) & shift & goto CheckOpts +if NOT "%1"=="" (echo unrecognized option %1) & goto Arm32SshHelp + +if "%arm32_ssh%"=="true" goto :Arm32Ssh + +:Arm32Ssh +if "%SSH_SERVER%"=="" goto :Arm32SshHelp + +ssh %SSH_SERVER% echo Make sure we can find SSH and SSH_SERVER variable is valid +if %ERRORLEVEL% NEQ 0 (echo SSH does not work) & exit /b %ERRORLEVEL% + +if "%PYTHON_SOURCE%"=="" (set PYTHON_SOURCE=%here%..\..\) +if "%REMOTE_PYTHON_DIR%"=="" (set REMOTE_PYTHON_DIR=C:\python\) +if NOT "%REMOTE_PYTHON_DIR:~-1,1%"=="\" (set REMOTE_PYTHON_DIR=%REMOTE_PYTHON_DIR%\) +echo PYTHON_SOURCE = %PYTHON_SOURCE% +echo REMOTE_PYTHON_DIR = %REMOTE_PYTHON_DIR% + +ssh %SSH_SERVER% "if EXIST %REMOTE_PYTHON_DIR% (rd %REMOTE_PYTHON_DIR% /s/q)" +ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%PCBuild\arm32" +ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%temp" +ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%Modules" +ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%PC" +for /f "USEBACKQ" %%i in (`dir PCbuild\*.bat /b`) do @scp PCBuild\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild" +for /f "USEBACKQ" %%i in (`dir PCbuild\*.py /b`) do @scp PCBuild\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild" +for /f "USEBACKQ" %%i in (`dir PCbuild\arm32\*.exe /b`) do @scp PCBuild\arm32\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild\arm32" +for /f "USEBACKQ" %%i in (`dir PCbuild\arm32\*.pyd /b`) do @scp PCBuild\arm32\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild\arm32" +for /f "USEBACKQ" %%i in (`dir PCbuild\arm32\*.dll /b`) do @scp PCBuild\arm32\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild\arm32" +scp -r "%PYTHON_SOURCE%Include" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Include" +scp -r "%PYTHON_SOURCE%Lib" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Lib" +scp -r "%PYTHON_SOURCE%Parser" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Parser" +scp -r "%PYTHON_SOURCE%Tools" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Tools" +scp "%PYTHON_SOURCE%Modules\Setup" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Modules" +scp "%PYTHON_SOURCE%PC\pyconfig.h" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PC" + +exit /b %ERRORLEVEL% + +:Arm32SshHelp +echo SSH_SERVER environment variable must be set to administrator@[ip address] +echo where [ip address] is the address of a Windows IoT Core ARM32 device. +echo. +echo The test worker should have the SSH agent running. +echo Also a key must be created with ssh-keygen and added to both the buildbot worker machine +echo and the ARM32 worker device: see https://docs.microsoft.com/en-us/windows/iot-core/connect-your-device/ssh +exit /b 127 diff --git a/Tools/buildbot/remotePythonInfo.bat b/Tools/buildbot/remotePythonInfo.bat new file mode 100644 index 00000000000000..b17717cb018ece --- /dev/null +++ b/Tools/buildbot/remotePythonInfo.bat @@ -0,0 +1,35 @@ +@echo off +rem Used by the buildbot "remotedeploy" step. +setlocal + +set PATH=%PATH%;%SystemRoot%\SysNative\OpenSSH;%SystemRoot%\System32\OpenSSH +set here=%~dp0 +set arm32_ssh= +set suffix=_d +if "%REMOTE_PYTHON_DIR%"=="" (set REMOTE_PYTHON_DIR=C:\python\) +if NOT "%REMOTE_PYTHON_DIR:~-1,1%"=="\" (set REMOTE_PYTHON_DIR=%REMOTE_PYTHON_DIR%\) + +:CheckOpts +if "%1"=="-arm32" (set arm32_ssh=true) & (set prefix=%REMOTE_PYTHON_DIR%pcbuild\arm32) & shift & goto CheckOpts +if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts +if "%1"=="+d" (set suffix=) & shift & goto CheckOpts +if NOT "%1"=="" (echo unrecognized option %1) & goto Arm32SshHelp + +if "%arm32_ssh%"=="true" goto :Arm32Ssh + +:Arm32Ssh +if "%SSH_SERVER%"=="" goto :Arm32SshHelp + +set PYTHON_EXE=%prefix%\python%suffix%.exe +echo on +ssh %SSH_SERVER% %PYTHON_EXE% -m test.pythoninfo +exit /b %ERRORLEVEL% + +:Arm32SshHelp +echo SSH_SERVER environment variable must be set to administrator@[ip address] +echo where [ip address] is the address of a Windows IoT Core ARM32 device. +echo. +echo The test worker should have the SSH agent running. +echo Also a key must be created with ssh-keygen and added to both the buildbot worker machine +echo and the ARM32 worker device: see https://docs.microsoft.com/en-us/windows/iot-core/connect-your-device/ssh +exit /b 127 diff --git a/Tools/buildbot/test.bat b/Tools/buildbot/test.bat index f430680f3d80cf..a0fc6b9a9458bc 100644 --- a/Tools/buildbot/test.bat +++ b/Tools/buildbot/test.bat @@ -2,6 +2,7 @@ rem Used by the buildbot "test" step. setlocal +set PATH=%PATH%;%SystemRoot%\SysNative\OpenSSH;%SystemRoot%\System32\OpenSSH set here=%~dp0 set rt_opts=-q -d set regrtest_args=-j1 @@ -9,6 +10,7 @@ set arm32_ssh= :CheckOpts if "%1"=="-x64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="-arm64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts if "%1"=="-arm32" (set rt_opts=%rt_opts% %1) & (set arm32_ssh=true) & shift & goto CheckOpts if "%1"=="-d" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts if "%1"=="-O" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts @@ -17,28 +19,21 @@ if "%1"=="+d" (set rt_opts=%rt_opts:-d=%) & shift & goto CheckOpts if "%1"=="+q" (set rt_opts=%rt_opts:-q=%) & shift & goto CheckOpts if NOT "%1"=="" (set regrtest_args=%regrtest_args% %1) & shift & goto CheckOpts -echo on +if "%PROCESSOR_ARCHITECTURE%"=="ARM" if "%arm32_ssh%"=="true" goto NativeExecution if "%arm32_ssh%"=="true" goto :Arm32Ssh +:NativeExecution call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --slowest --timeout=1200 --fail-env-changed %regrtest_args% exit /b %ERRORLEVEL% :Arm32Ssh -set dashU=-unetwork,decimal,subprocess,urlfetch,tzdata +set dashU=-unetwork -udecimal -usubprocess -uurlfetch -utzdata if "%SSH_SERVER%"=="" goto :Arm32SshHelp if "%PYTHON_SOURCE%"=="" (set PYTHON_SOURCE=%here%..\..\) if "%REMOTE_PYTHON_DIR%"=="" (set REMOTE_PYTHON_DIR=C:\python\) +if NOT "%REMOTE_PYTHON_DIR:~-1,1%"=="\" (set REMOTE_PYTHON_DIR=%REMOTE_PYTHON_DIR%\) + set TEMP_ARGS=--temp %REMOTE_PYTHON_DIR%temp -ssh %SSH_SERVER% "if EXIST %REMOTE_PYTHON_DIR% (rd %REMOTE_PYTHON_DIR% /s/q)" -ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%PCBuild\arm32" -ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%temp" -for /f "USEBACKQ" %%i in (`dir PCbuild\*.bat /b`) do @scp PCBuild\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild" -for /f "USEBACKQ" %%i in (`dir PCbuild\*.py /b`) do @scp PCBuild\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild" -for /f "USEBACKQ" %%i in (`dir PCbuild\arm32\*.exe /b`) do @scp PCBuild\arm32\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild\arm32" -for /f "USEBACKQ" %%i in (`dir PCbuild\arm32\*.pyd /b`) do @scp PCBuild\arm32\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild\arm32" -for /f "USEBACKQ" %%i in (`dir PCbuild\arm32\*.dll /b`) do @scp PCBuild\arm32\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild\arm32" -scp -r "%PYTHON_SOURCE%Include" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Include" -scp -r "%PYTHON_SOURCE%Lib" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Lib" set rt_args=%rt_opts% %dashU% -rwW --slowest --timeout=1200 --fail-env-changed %regrtest_args% %TEMP_ARGS% ssh %SSH_SERVER% "set TEMP=%REMOTE_PYTHON_DIR%temp& %REMOTE_PYTHON_DIR%PCbuild\rt.bat" %rt_args% diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 9880b395133995..c5edc7c9336fb1 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -43,9 +43,6 @@ version = '1' -_empty = inspect._empty -_void = inspect._void - NoneType = type(None) class Unspecified: @@ -806,7 +803,8 @@ def parser_body(prototype, *fields, declarations=''): {c_basename}({self_type}{self_name}, PyObject *%s) """ % argname) - parsearg = converters[0].parse_arg(argname, 0) + displayname = parameters[0].get_displayname(0) + parsearg = converters[0].parse_arg(argname, displayname) if parsearg is None: parsearg = """ if (!PyArg_Parse(%s, "{format_units}:{name}", {parse_arguments})) {{ @@ -851,7 +849,8 @@ def parser_body(prototype, *fields, declarations=''): """ % (nargs, min_pos, max_pos), indent=4)] has_optional = False for i, p in enumerate(parameters): - parsearg = p.converter.parse_arg(argname_fmt % i, i + 1) + displayname = p.get_displayname(i+1) + parsearg = p.converter.parse_arg(argname_fmt % i, displayname) if parsearg is None: #print('Cannot convert %s %r for %s' % (p.converter.__class__.__name__, p.converter.format_unit, p.converter.name), file=sys.stderr) parser_code = None @@ -927,7 +926,8 @@ def parser_body(prototype, *fields, declarations=''): add_label = None for i, p in enumerate(parameters): - parsearg = p.converter.parse_arg(argname_fmt % i, i + 1) + displayname = p.get_displayname(i+1) + parsearg = p.converter.parse_arg(argname_fmt % i, displayname) if parsearg is None: #print('Cannot convert %s %r for %s' % (p.converter.__class__.__name__, p.converter.format_unit, p.converter.name), file=sys.stderr) parser_code = None @@ -2172,7 +2172,7 @@ class Function: def __init__(self, parameters=None, *, name, module, cls=None, c_basename=None, full_name=None, - return_converter, return_annotation=_empty, + return_converter, return_annotation=inspect.Signature.empty, docstring=None, kind=CALLABLE, coexist=False, docstring_only=False): self.parameters = parameters or collections.OrderedDict() @@ -2250,8 +2250,8 @@ class Parameter: Mutable duck type of inspect.Parameter. """ - def __init__(self, name, kind, *, default=_empty, - function, converter, annotation=_empty, + def __init__(self, name, kind, *, default=inspect.Parameter.empty, + function, converter, annotation=inspect.Parameter.empty, docstring=None, group=0): self.name = name self.kind = kind @@ -2287,6 +2287,13 @@ def copy(self, **overrides): kwargs['converter'] = converter return Parameter(**kwargs) + def get_displayname(self, i): + if i == 0: + return '"argument"' + if not self.is_positional_only(): + return '''"argument '{}'"'''.format(self.name) + else: + return '"argument {}"'.format(i) class LandMine: @@ -2634,7 +2641,7 @@ def pre_render(self): """ pass - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'O&': return """ if (!{converter}({argname}, &{paramname})) {{{{ @@ -2648,21 +2655,22 @@ def parse_arg(self, argname, argnum): typecheck, typename = type_checks[self.subclass_of] return """ if (!{typecheck}({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "{typename}", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "{typename}", {argname}); goto exit; }}}} {paramname} = {cast}{argname}; """.format(argname=argname, paramname=self.name, - argnum=argnum, - typecheck=typecheck, typename=typename, cast=cast) + displayname=displayname, typecheck=typecheck, + typename=typename, cast=cast) return """ if (!PyObject_TypeCheck({argname}, {subclass_of})) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, ({subclass_of})->tp_name, {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, ({subclass_of})->tp_name, {argname}); goto exit; }}}} {paramname} = {cast}{argname}; - """.format(argname=argname, paramname=self.name, argnum=argnum, - subclass_of=self.subclass_of, cast=cast) + """.format(argname=argname, paramname=self.name, + subclass_of=self.subclass_of, cast=cast, + displayname=displayname) if self.format_unit == 'O': cast = '(%s)' % self.type if self.type != 'PyObject *' else '' return """ @@ -2698,7 +2706,7 @@ def converter_init(self, *, accept={object}): self.default = bool(self.default) self.c_default = str(int(self.default)) - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'i': # XXX PyFloat_Check can be removed after the end of the # deprecation in _PyLong_FromNbIndexOrNbInt. @@ -2720,7 +2728,7 @@ def parse_arg(self, argname, argnum): goto exit; }}}} """.format(argname=argname, paramname=self.name) - return super().parse_arg(argname, argnum) + return super().parse_arg(argname, displayname) class char_converter(CConverter): type = 'char' @@ -2737,7 +2745,7 @@ def converter_init(self): if self.c_default == '"\'"': self.c_default = r"'\''" - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'c': return """ if (PyBytes_Check({argname}) && PyBytes_GET_SIZE({argname}) == 1) {{{{ @@ -2747,11 +2755,12 @@ def parse_arg(self, argname, argnum): {paramname} = PyByteArray_AS_STRING({argname})[0]; }}}} else {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "a byte string of length 1", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "a byte string of length 1", {argname}); goto exit; }}}} - """.format(argname=argname, paramname=self.name, argnum=argnum) - return super().parse_arg(argname, argnum) + """.format(argname=argname, paramname=self.name, + displayname=displayname) + return super().parse_arg(argname, displayname) @add_legacy_c_converter('B', bitwise=True) @@ -2765,7 +2774,7 @@ def converter_init(self, *, bitwise=False): if bitwise: self.format_unit = 'B' - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'b': return """ if (PyFloat_Check({argname})) {{{{ @@ -2810,7 +2819,7 @@ def parse_arg(self, argname, argnum): }}}} }}}} """.format(argname=argname, paramname=self.name) - return super().parse_arg(argname, argnum) + return super().parse_arg(argname, displayname) class byte_converter(unsigned_char_converter): pass @@ -2820,7 +2829,7 @@ class short_converter(CConverter): format_unit = 'h' c_ignored_default = "0" - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'h': return """ if (PyFloat_Check({argname})) {{{{ @@ -2848,7 +2857,7 @@ def parse_arg(self, argname, argnum): }}}} }}}} """.format(argname=argname, paramname=self.name) - return super().parse_arg(argname, argnum) + return super().parse_arg(argname, displayname) class unsigned_short_converter(CConverter): type = 'unsigned short' @@ -2861,7 +2870,7 @@ def converter_init(self, *, bitwise=False): else: self.converter = '_PyLong_UnsignedShort_Converter' - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'H': return """ if (PyFloat_Check({argname})) {{{{ @@ -2874,7 +2883,7 @@ def parse_arg(self, argname, argnum): goto exit; }}}} """.format(argname=argname, paramname=self.name) - return super().parse_arg(argname, argnum) + return super().parse_arg(argname, displayname) @add_legacy_c_converter('C', accept={str}) class int_converter(CConverter): @@ -2891,7 +2900,7 @@ def converter_init(self, *, accept={int}, type=None): if type != None: self.type = type - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'i': return """ if (PyFloat_Check({argname})) {{{{ @@ -2907,19 +2916,20 @@ def parse_arg(self, argname, argnum): elif self.format_unit == 'C': return """ if (!PyUnicode_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "a unicode character", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "a unicode character", {argname}); goto exit; }}}} if (PyUnicode_READY({argname})) {{{{ goto exit; }}}} if (PyUnicode_GET_LENGTH({argname}) != 1) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "a unicode character", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "a unicode character", {argname}); goto exit; }}}} {paramname} = PyUnicode_READ_CHAR({argname}, 0); - """.format(argname=argname, paramname=self.name, argnum=argnum) - return super().parse_arg(argname, argnum) + """.format(argname=argname, paramname=self.name, + displayname=displayname) + return super().parse_arg(argname, displayname) class unsigned_int_converter(CConverter): type = 'unsigned int' @@ -2932,7 +2942,7 @@ def converter_init(self, *, bitwise=False): else: self.converter = '_PyLong_UnsignedInt_Converter' - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'I': return """ if (PyFloat_Check({argname})) {{{{ @@ -2945,7 +2955,7 @@ def parse_arg(self, argname, argnum): goto exit; }}}} """.format(argname=argname, paramname=self.name) - return super().parse_arg(argname, argnum) + return super().parse_arg(argname, displayname) class long_converter(CConverter): type = 'long' @@ -2953,7 +2963,7 @@ class long_converter(CConverter): format_unit = 'l' c_ignored_default = "0" - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'l': return """ if (PyFloat_Check({argname})) {{{{ @@ -2966,7 +2976,7 @@ def parse_arg(self, argname, argnum): goto exit; }}}} """.format(argname=argname, paramname=self.name) - return super().parse_arg(argname, argnum) + return super().parse_arg(argname, displayname) class unsigned_long_converter(CConverter): type = 'unsigned long' @@ -2979,16 +2989,17 @@ def converter_init(self, *, bitwise=False): else: self.converter = '_PyLong_UnsignedLong_Converter' - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'k': return """ if (!PyLong_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "int", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "int", {argname}); goto exit; }}}} {paramname} = PyLong_AsUnsignedLongMask({argname}); - """.format(argname=argname, paramname=self.name, argnum=argnum) - return super().parse_arg(argname, argnum) + """.format(argname=argname, paramname=self.name, + displayname=displayname) + return super().parse_arg(argname, displayname) class long_long_converter(CConverter): type = 'long long' @@ -2996,7 +3007,7 @@ class long_long_converter(CConverter): format_unit = 'L' c_ignored_default = "0" - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'L': return """ if (PyFloat_Check({argname})) {{{{ @@ -3009,7 +3020,7 @@ def parse_arg(self, argname, argnum): goto exit; }}}} """.format(argname=argname, paramname=self.name) - return super().parse_arg(argname, argnum) + return super().parse_arg(argname, displayname) class unsigned_long_long_converter(CConverter): type = 'unsigned long long' @@ -3022,16 +3033,17 @@ def converter_init(self, *, bitwise=False): else: self.converter = '_PyLong_UnsignedLongLong_Converter' - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'K': return """ if (!PyLong_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "int", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "int", {argname}); goto exit; }}}} {paramname} = PyLong_AsUnsignedLongLongMask({argname}); - """.format(argname=argname, paramname=self.name, argnum=argnum) - return super().parse_arg(argname, argnum) + """.format(argname=argname, paramname=self.name, + displayname=displayname) + return super().parse_arg(argname, displayname) class Py_ssize_t_converter(CConverter): type = 'Py_ssize_t' @@ -3046,7 +3058,7 @@ def converter_init(self, *, accept={int}): else: fail("Py_ssize_t_converter: illegal 'accept' argument " + repr(accept)) - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'n': return """ if (PyFloat_Check({argname})) {{{{ @@ -3067,7 +3079,7 @@ def parse_arg(self, argname, argnum): {paramname} = ival; }}}} """.format(argname=argname, paramname=self.name) - return super().parse_arg(argname, argnum) + return super().parse_arg(argname, displayname) class slice_index_converter(CConverter): @@ -3086,7 +3098,7 @@ class size_t_converter(CConverter): converter = '_PyLong_Size_t_Converter' c_ignored_default = "0" - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'n': return """ {paramname} = PyNumber_AsSsize_t({argname}, PyExc_OverflowError); @@ -3094,7 +3106,7 @@ def parse_arg(self, argname, argnum): goto exit; }}}} """.format(argname=argname, paramname=self.name) - return super().parse_arg(argname, argnum) + return super().parse_arg(argname, displayname) class float_converter(CConverter): @@ -3103,15 +3115,21 @@ class float_converter(CConverter): format_unit = 'f' c_ignored_default = "0.0" - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'f': return """ - {paramname} = (float) PyFloat_AsDouble({argname}); - if (PyErr_Occurred()) {{{{ - goto exit; + if (PyFloat_CheckExact({argname})) {{{{ + {paramname} = (float) (PyFloat_AS_DOUBLE({argname})); + }}}} + else + {{{{ + {paramname} = (float) PyFloat_AsDouble({argname}); + if ({paramname} == -1.0 && PyErr_Occurred()) {{{{ + goto exit; + }}}} }}}} """.format(argname=argname, paramname=self.name) - return super().parse_arg(argname, argnum) + return super().parse_arg(argname, displayname) class double_converter(CConverter): type = 'double' @@ -3119,15 +3137,21 @@ class double_converter(CConverter): format_unit = 'd' c_ignored_default = "0.0" - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'd': return """ - {paramname} = PyFloat_AsDouble({argname}); - if (PyErr_Occurred()) {{{{ - goto exit; + if (PyFloat_CheckExact({argname})) {{{{ + {paramname} = PyFloat_AS_DOUBLE({argname}); + }}}} + else + {{{{ + {paramname} = PyFloat_AsDouble({argname}); + if ({paramname} == -1.0 && PyErr_Occurred()) {{{{ + goto exit; + }}}} }}}} """.format(argname=argname, paramname=self.name) - return super().parse_arg(argname, argnum) + return super().parse_arg(argname, displayname) class Py_complex_converter(CConverter): @@ -3136,7 +3160,7 @@ class Py_complex_converter(CConverter): format_unit = 'D' c_ignored_default = "{0.0, 0.0}" - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'D': return """ {paramname} = PyComplex_AsCComplex({argname}); @@ -3144,7 +3168,7 @@ def parse_arg(self, argname, argnum): goto exit; }}}} """.format(argname=argname, paramname=self.name) - return super().parse_arg(argname, argnum) + return super().parse_arg(argname, displayname) class object_converter(CConverter): @@ -3204,17 +3228,19 @@ def converter_init(self, *, accept={str}, encoding=None, zeroes=False): # sorry, clinic can't support preallocated buffers # for es# and et# self.c_default = "NULL" + if NoneType in accept and self.c_default == "Py_None": + self.c_default = "NULL" def cleanup(self): if self.encoding: name = self.name return "".join(["if (", name, ") {\n PyMem_FREE(", name, ");\n}\n"]) - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 's': return """ if (!PyUnicode_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "str", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "str", {argname}); goto exit; }}}} Py_ssize_t {paramname}_length; @@ -3226,7 +3252,8 @@ def parse_arg(self, argname, argnum): PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; }}}} - """.format(argname=argname, paramname=self.name, argnum=argnum) + """.format(argname=argname, paramname=self.name, + displayname=displayname) if self.format_unit == 'z': return """ if ({argname} == Py_None) {{{{ @@ -3244,11 +3271,12 @@ def parse_arg(self, argname, argnum): }}}} }}}} else {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "str or None", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "str or None", {argname}); goto exit; }}}} - """.format(argname=argname, paramname=self.name, argnum=argnum) - return super().parse_arg(argname, argnum) + """.format(argname=argname, paramname=self.name, + displayname=displayname) + return super().parse_arg(argname, displayname) # # This is the fourth or fifth rewrite of registering all the @@ -3303,53 +3331,54 @@ class PyBytesObject_converter(CConverter): format_unit = 'S' # accept = {bytes} - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'S': return """ if (!PyBytes_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "bytes", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "bytes", {argname}); goto exit; }}}} {paramname} = ({type}){argname}; - """.format(argname=argname, paramname=self.name, argnum=argnum, - type=self.type) - return super().parse_arg(argname, argnum) + """.format(argname=argname, paramname=self.name, + type=self.type, displayname=displayname) + return super().parse_arg(argname, displayname) class PyByteArrayObject_converter(CConverter): type = 'PyByteArrayObject *' format_unit = 'Y' # accept = {bytearray} - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'Y': return """ if (!PyByteArray_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "bytearray", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "bytearray", {argname}); goto exit; }}}} {paramname} = ({type}){argname}; - """.format(argname=argname, paramname=self.name, argnum=argnum, - type=self.type) - return super().parse_arg(argname, argnum) + """.format(argname=argname, paramname=self.name, + type=self.type, displayname=displayname) + return super().parse_arg(argname, displayname) class unicode_converter(CConverter): type = 'PyObject *' default_type = (str, Null, NoneType) format_unit = 'U' - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'U': return """ if (!PyUnicode_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "str", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "str", {argname}); goto exit; }}}} if (PyUnicode_READY({argname}) == -1) {{{{ goto exit; }}}} {paramname} = {argname}; - """.format(argname=argname, paramname=self.name, argnum=argnum) - return super().parse_arg(argname, argnum) + """.format(argname=argname, paramname=self.name, + displayname=displayname) + return super().parse_arg(argname, displayname) @add_legacy_c_converter('u#', zeroes=True) @add_legacy_c_converter('Z', accept={str, NoneType}) @@ -3398,17 +3427,18 @@ def cleanup(self): name = self.name return "".join(["if (", name, ".obj) {\n PyBuffer_Release(&", name, ");\n}\n"]) - def parse_arg(self, argname, argnum): + def parse_arg(self, argname, displayname): if self.format_unit == 'y*': return """ if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{ goto exit; }}}} if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "contiguous buffer", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "contiguous buffer", {argname}); goto exit; }}}} - """.format(argname=argname, paramname=self.name, argnum=argnum) + """.format(argname=argname, paramname=self.name, + displayname=displayname) elif self.format_unit == 's*': return """ if (PyUnicode_Check({argname})) {{{{ @@ -3424,24 +3454,26 @@ def parse_arg(self, argname, argnum): goto exit; }}}} if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "contiguous buffer", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "contiguous buffer", {argname}); goto exit; }}}} }}}} - """.format(argname=argname, paramname=self.name, argnum=argnum) + """.format(argname=argname, paramname=self.name, + displayname=displayname) elif self.format_unit == 'w*': return """ if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_WRITABLE) < 0) {{{{ PyErr_Clear(); - _PyArg_BadArgument("{{name}}", {argnum}, "read-write bytes-like object", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "read-write bytes-like object", {argname}); goto exit; }}}} if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "contiguous buffer", {argname}); + _PyArg_BadArgument("{{name}}", {displayname}, "contiguous buffer", {argname}); goto exit; }}}} - """.format(argname=argname, paramname=self.name, argnum=argnum) - return super().parse_arg(argname, argnum) + """.format(argname=argname, paramname=self.name, + displayname=displayname) + return super().parse_arg(argname, displayname) def correct_name_for_self(f): @@ -4400,7 +4432,7 @@ def bad_node(self, node): # mild hack: explicitly support NULL as a default value if isinstance(expr, ast.Name) and expr.id == 'NULL': value = NULL - py_default = 'None' + py_default = '' c_default = "NULL" elif (isinstance(expr, ast.BinOp) or (isinstance(expr, ast.UnaryOp) and diff --git a/Tools/demo/eiffel.py b/Tools/demo/eiffel.py index 736abea81738c8..a76c2324dd6a67 100755 --- a/Tools/demo/eiffel.py +++ b/Tools/demo/eiffel.py @@ -78,7 +78,7 @@ def __init__(self, func, pre, post): self.__name__ = func.__name__ self.__doc__ = func.__doc__ - def __get__(self, obj, cls): + def __get__(self, obj, cls=None): return EiffelMethodWrapper(obj, self) def callmethod(self, inst, args, kwargs): diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 93f720ab7e2a10..93f997c21e7706 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1392,7 +1392,7 @@ def write_repr(self, out, visited): def int_from_int(gdbval): - return int(str(gdbval)) + return int(gdbval) def stringify(val): @@ -1563,9 +1563,8 @@ def is_other_python_frame(self): if not caller: return False - if caller in ('_PyCFunction_FastCallDict', - '_PyCFunction_Vectorcall', - 'cfunction_call_varargs'): + if (caller.startswith('cfunction_vectorcall_') or + caller == 'cfunction_call_varargs'): arg_name = 'func' # Within that frame: # "func" is the local containing the PyObject* of the diff --git a/Tools/msi/README.txt b/Tools/msi/README.txt index 07ea9f744bd0bb..f5656b971b3cec 100644 --- a/Tools/msi/README.txt +++ b/Tools/msi/README.txt @@ -159,9 +159,7 @@ The following properties may be passed when building these projects. /p:BuildForRelease=(true|false) When true, adds extra verification to ensure a complete installer is - produced. For example, binutils is required when building for a release - to generate MinGW-compatible libraries, and the build will be aborted if - this fails. Defaults to false. + produced. Defaults to false. /p:ReleaseUri=(any URI) Used to generate unique IDs for the installers to allow side-by-side diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index 45e189b537f693..b72eedecb23cf2 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -29,7 +29,7 @@ set DOWNLOAD_URL=https://www.python.org/ftp/python/{version}/{arch}{releasename} set D=%~dp0 set PCBUILD=%D%..\..\PCbuild\ -if "%Py_OutDir%"=="" set Py_OutDir=%PCBUILD% +if NOT DEFINED Py_OutDir set Py_OutDir=%PCBUILD% set EXTERNALS=%D%..\..\externals\windows-installer\ set BUILDX86= diff --git a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp index 7cd8fb8e058303..570798de1aafa8 100644 --- a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp +++ b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp @@ -727,9 +727,13 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load AssociateFiles state: error code 0x%08X", hr); } - _engine->SetVariableNumeric(L"Include_launcher", 1); + LONGLONG includeLauncher; + if (FAILED(BalGetNumericVariable(L"Include_launcher", &includeLauncher)) + || includeLauncher == -1) { + _engine->SetVariableNumeric(L"Include_launcher", 1); + _engine->SetVariableNumeric(L"InstallLauncherAllUsers", fPerMachine ? 1 : 0); + } _engine->SetVariableNumeric(L"DetectedOldLauncher", 1); - _engine->SetVariableNumeric(L"InstallLauncherAllUsers", fPerMachine ? 1 : 0); } return CheckCanceled() ? IDCANCEL : IDNOACTION; } @@ -796,6 +800,12 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { } } + LONGLONG includeLauncher; + if (SUCCEEDED(BalGetNumericVariable(L"Include_launcher", &includeLauncher)) + && includeLauncher != -1) { + detectedLauncher = FALSE; + } + if (detectedLauncher) { /* When we detect the current version of the launcher. */ _engine->SetVariableNumeric(L"Include_launcher", 1); @@ -819,6 +829,14 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { _baFunction->OnDetectComplete(); } + if (SUCCEEDED(hrStatus)) { + LONGLONG includeLauncher; + if (SUCCEEDED(BalGetNumericVariable(L"Include_launcher", &includeLauncher)) + && includeLauncher == -1) { + _engine->SetVariableNumeric(L"Include_launcher", 1); + } + } + if (SUCCEEDED(hrStatus)) { hrStatus = EvaluateConditions(); } @@ -1451,6 +1469,10 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { hr = ParseOverridableVariablesFromXml(pixdManifest); BalExitOnFailure(hr, "Failed to read overridable variables."); + if (_command.action == BOOTSTRAPPER_ACTION_MODIFY) { + LoadOptionalFeatureStates(_engine); + } + hr = ParseVariablesFromUnattendXml(); ExitOnFailure(hr, "Failed to read unattend.ini file."); @@ -1478,10 +1500,6 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { hr = UpdateUIStrings(_command.action); BalExitOnFailure(hr, "Failed to load UI strings."); - if (_command.action == BOOTSTRAPPER_ACTION_MODIFY) { - LoadOptionalFeatureStates(_engine); - } - GetBundleFileVersion(); // don't fail if we couldn't get the version info; best-effort only LExit: diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs index f6cff6fc351dc1..ddd6870f625526 100644 --- a/Tools/msi/bundle/bundle.wxs +++ b/Tools/msi/bundle/bundle.wxs @@ -71,11 +71,10 @@ + - - diff --git a/Tools/msi/dev/dev.wixproj b/Tools/msi/dev/dev.wixproj index 4a56cec35722cf..4052e4b5368273 100644 --- a/Tools/msi/dev/dev.wixproj +++ b/Tools/msi/dev/dev.wixproj @@ -7,12 +7,6 @@ Package - - - $(DefineConstants); - IncludeMinGWLib=1; - - @@ -31,20 +25,5 @@ - - - - <_DllToolOpts>-m i386 --as-flags=--32 - <_DllToolOpts Condition="$(Platform) == 'x64'">-m i386:x86-64 - - - - - - diff --git a/Tools/msi/dev/dev.wxs b/Tools/msi/dev/dev.wxs index a09e139c428bf1..23a710df87d55c 100644 --- a/Tools/msi/dev/dev.wxs +++ b/Tools/msi/dev/dev.wxs @@ -10,9 +10,6 @@ - - - diff --git a/Tools/msi/dev/dev_files.wxs b/Tools/msi/dev/dev_files.wxs index 9654d2e3e600f0..21f9c848cc6be5 100644 --- a/Tools/msi/dev/dev_files.wxs +++ b/Tools/msi/dev/dev_files.wxs @@ -29,14 +29,4 @@ - - - - - - - - - - diff --git a/Tools/msi/exe/exe.wixproj b/Tools/msi/exe/exe.wixproj index 071501ce6e6f57..326766bf2d473f 100644 --- a/Tools/msi/exe/exe.wixproj +++ b/Tools/msi/exe/exe.wixproj @@ -21,25 +21,6 @@ - - - - <_LicenseFiles Include="@(LicenseFiles)"> - $([System.IO.File]::ReadAllText(%(FullPath))) - - - - - - diff --git a/Tools/msi/exe/exe_files.wxs b/Tools/msi/exe/exe_files.wxs index 394b4de473547f..483d06c65b2e57 100644 --- a/Tools/msi/exe/exe_files.wxs +++ b/Tools/msi/exe/exe_files.wxs @@ -3,7 +3,7 @@ - + diff --git a/Tools/msi/make_cat.ps1 b/Tools/msi/make_cat.ps1 index cc3cd4a2b50cda..9ea3ddd495719e 100644 --- a/Tools/msi/make_cat.ps1 +++ b/Tools/msi/make_cat.ps1 @@ -7,6 +7,8 @@ The path to the catalog definition file to compile and sign. It is assumed that the .cat file will be the same name with a new extension. +.Parameter outfile + The path to move the built .cat file to (optional). .Parameter description The description to add to the signature (optional). .Parameter certname @@ -16,6 +18,7 @@ #> param( [Parameter(Mandatory=$true)][string]$catalog, + [string]$outfile, [switch]$sign, [string]$description, [string]$certname, @@ -35,3 +38,8 @@ if (-not $?) { if ($sign) { Sign-File -certname $certname -certsha1 $certsha1 -certfile $certfile -description $description -files @($catalog -replace 'cdf$', 'cat') } + +if ($outfile) { + Split-Path -Parent $outfile | ?{ $_ } | %{ mkdir -Force $_; } + Move-Item ($catalog -replace 'cdf$', 'cat') $outfile +} diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props index 0fe822af93194b..3f14501446a15a 100644 --- a/Tools/msi/msi.props +++ b/Tools/msi/msi.props @@ -56,6 +56,7 @@ true $(ExternalsDir)\windows-installer\redist-1\$(Platform) $([System.IO.Path]::GetFullPath($(CRTRedist))) + $(tcltkDir)lib python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm $(MajorVersionNumber).$(MinorVersionNumber).$(Field3Value).0 @@ -87,15 +88,16 @@ PyArchExt=$(PyArchExt); PyTestExt=$(PyTestExt); OptionalFeatureName=$(OutputName); + ssltag=-1_1; $(DefineConstants);CRTRedist=$(CRTRedist); - $(DefineConstants);Suffix32=-32;ssltag=-1_1; + $(DefineConstants);Suffix32=-32; - $(DefineConstants);Suffix32=;ssltag=-1_1-x64; + $(DefineConstants);Suffix32=; @@ -120,7 +122,7 @@ src - + tcltk diff --git a/Tools/msi/msi.targets b/Tools/msi/msi.targets index 9283a1ed6c3049..4788a637a5d2d6 100644 --- a/Tools/msi/msi.targets +++ b/Tools/msi/msi.targets @@ -47,7 +47,7 @@ EncodingType= - @@ -76,18 +76,18 @@ EncodingType= - + - + - + - + \ No newline at end of file diff --git a/Tools/msi/sign_build.ps1 b/Tools/msi/sign_build.ps1 index 6668eb33a2d135..d3f750454f522b 100644 --- a/Tools/msi/sign_build.ps1 +++ b/Tools/msi/sign_build.ps1 @@ -16,7 +16,7 @@ #> param( [Parameter(Mandatory=$true)][string]$root, - [string[]]$patterns=@("*.exe", "*.dll", "*.pyd"), + [string[]]$patterns=@("*.exe", "*.dll", "*.pyd", "*.cat"), [string]$description, [string]$certname, [string]$certsha1, diff --git a/Tools/msi/tcltk/tcltk.wixproj b/Tools/msi/tcltk/tcltk.wixproj index fae353f5f50a7d..218f3d15ec88fc 100644 --- a/Tools/msi/tcltk/tcltk.wixproj +++ b/Tools/msi/tcltk/tcltk.wixproj @@ -20,10 +20,10 @@ - - $(tcltkDir) + + $(TclTkLibraryDir) !(bindpath.tcltk) - $(tcltkDir)lib + $(TclTkLibraryDir) tcl\ tcltk_lib diff --git a/Tools/msi/uploadrelease.ps1 b/Tools/msi/uploadrelease.ps1 index 491df80be1e9b0..d3673b4582983c 100644 --- a/Tools/msi/uploadrelease.ps1 +++ b/Tools/msi/uploadrelease.ps1 @@ -15,6 +15,10 @@ The subdirectory on the host to copy files to. .Parameter tests The path to run download tests in. +.Parameter doc_htmlhelp + Optional path besides -build to locate CHM files. +.Parameter embed + Optional path besides -build to locate ZIP files. .Parameter skipupload Skip uploading .Parameter skippurge @@ -30,6 +34,8 @@ param( [string]$server="python-downloads", [string]$target="/srv/www.python.org/ftp/python", [string]$tests=${env:TEMP}, + [string]$doc_htmlhelp=$null, + [string]$embed=$null, [switch]$skipupload, [switch]$skippurge, [switch]$skiptest, @@ -73,36 +79,53 @@ if (-not $skipupload) { "Upload using $pscp and $plink" "" - pushd $build - $doc = gci python*.chm, python*.chm.asc + if ($doc_htmlhelp) { + pushd $doc_htmlhelp + } else { + pushd $build + } + $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 g-x,o+rx $d - & $pscp -batch $doc.FullName "$user@${server}:$d" + & $pscp -batch $chm.FullName "$user@${server}:$d" + if (-not $?) { throw "Failed to upload $chm" } + + $dirs = gci "$build" -Directory + if ($embed) { + $dirs = ($dirs, (gi $embed)) | %{ $_ } + } - foreach ($a in gci "$build" -Directory) { + foreach ($a in $dirs) { "Uploading files from $($a.FullName)" pushd "$($a.FullName)" $exe = gci *.exe, *.exe.asc, *.zip, *.zip.asc $msi = gci *.msi, *.msi.asc, *.msu, *.msu.asc popd - & $pscp -batch $exe.FullName "$user@${server}:$d" + if ($exe) { + & $pscp -batch $exe.FullName "$user@${server}:$d" + if (-not $?) { throw "Failed to upload $exe" } + } - $sd = "$d$($a.Name)$($p[1])/" - & $plink -batch $user@$server mkdir $sd - & $plink -batch $user@$server chgrp downloads $sd - & $plink -batch $user@$server chmod g-x,o+rx $sd - & $pscp -batch $msi.FullName "$user@${server}:$sd" - & $plink -batch $user@$server chgrp downloads $sd* - & $plink -batch $user@$server chmod g-x,o+r $sd* + if ($msi) { + $sd = "$d$($a.Name)$($p[1])/" + & $plink -batch $user@$server mkdir $sd + & $plink -batch $user@$server chgrp downloads $sd + & $plink -batch $user@$server chmod g-x,o+rx $sd + & $pscp -batch $msi.FullName "$user@${server}:$sd" + if (-not $?) { throw "Failed to upload $msi" } + & $plink -batch $user@$server chgrp downloads $sd* + & $plink -batch $user@$server chmod g-x,o+r $sd* + } } & $plink -batch $user@$server chgrp downloads $d* & $plink -batch $user@$server chmod g-x,o+r $d* + & $pscp -ls "$user@${server}:$d" } if (-not $skippurge) { @@ -128,11 +151,21 @@ if (-not $skiptest) { if (-not $skiphash) { # Display MD5 hash and size of each downloadable file pushd $build - $hashes = gci python*.chm, *\*.exe, *\*.zip | ` + $files = gci python*.chm, *\*.exe, *\*.zip + if ($doc_htmlhelp) { + cd $doc_htmlhelp + $files = ($files, (gci python*.chm)) | %{ $_ } + } + if ($embed) { + cd $embed + $files = ($files, (gci *.zip)) | %{ $_ } + } + popd + + $hashes = $files | ` Sort-Object Name | ` Format-Table Name, @{Label="MD5"; Expression={(Get-FileHash $_ -Algorithm MD5).Hash}}, Length -AutoSize | ` Out-String -Width 4096 $hashes | clip $hashes - popd } diff --git a/Tools/scripts/pathfix.py b/Tools/scripts/pathfix.py index 1a0cf1c9e69ce7..d252321a21a172 100755 --- a/Tools/scripts/pathfix.py +++ b/Tools/scripts/pathfix.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Change the #! line occurring in Python scripts. The new interpreter +# 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. @@ -10,7 +10,13 @@ # 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 @@ -33,16 +39,21 @@ 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 - usage = ('usage: %s -i /interpreter -p -n file-or-directory ...\n' % + 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:pn') + opts, args = getopt.getopt(sys.argv[1:], 'i:a:kpn') except getopt.error as msg: err(str(msg) + '\n') err(usage) @@ -54,6 +65,13 @@ def main(): 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') @@ -70,9 +88,10 @@ def main(): if fix(arg): bad = 1 sys.exit(bad) -ispythonprog = re.compile(r'^[a-zA-Z0-9_]+\.py$') + def ispython(name): - return bool(ispythonprog.match(name)) + return name.endswith('.py') + def recursedown(dirname): dbg('recursedown(%r)\n' % (dirname,)) @@ -96,6 +115,7 @@ def recursedown(dirname): if recursedown(fullname): bad = 1 return bad + def fix(filename): ## dbg('fix(%r)\n' % (filename,)) try: @@ -164,12 +184,43 @@ def fix(filename): # 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 - return b'#! ' + new_interpreter + b'\n' + + flags = populate_flags(line) + return b'#! ' + new_interpreter + flags + b'\n' + if __name__ == '__main__': main() diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 7fda4df55a678b..d816810d57078d 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -45,17 +45,16 @@ ] OPENSSL_RECENT_VERSIONS = [ - "1.0.2s", - "1.1.0k", - "1.1.1c", + "1.0.2t", + "1.1.0l", + "1.1.1d", ] LIBRESSL_OLD_VERSIONS = [ - "2.9.2", ] LIBRESSL_RECENT_VERSIONS = [ - "2.8.3", + "2.9.2", ] # store files in ../multissl diff --git a/aclocal.m4 b/aclocal.m4 index 3d6b1a375fdca3..85f00dd5fac7f2 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -12,9 +12,9 @@ # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# serial 11 (pkg-config-0.29.1) - +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29.1) +dnl dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl @@ -288,73 +288,5 @@ AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR -dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, -dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], -dnl [DESCRIPTION], [DEFAULT]) -dnl ------------------------------------------ -dnl -dnl Prepare a "--with-" configure option using the lowercase -dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and -dnl PKG_CHECK_MODULES in a single macro. -AC_DEFUN([PKG_WITH_MODULES], -[ -m4_pushdef([with_arg], m4_tolower([$1])) - -m4_pushdef([description], - [m4_default([$5], [build with ]with_arg[ support])]) - -m4_pushdef([def_arg], [m4_default([$6], [auto])]) -m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) -m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) - -m4_case(def_arg, - [yes],[m4_pushdef([with_without], [--without-]with_arg)], - [m4_pushdef([with_without],[--with-]with_arg)]) - -AC_ARG_WITH(with_arg, - AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, - [AS_TR_SH([with_]with_arg)=def_arg]) - -AS_CASE([$AS_TR_SH([with_]with_arg)], - [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], - [auto],[PKG_CHECK_MODULES([$1],[$2], - [m4_n([def_action_if_found]) $3], - [m4_n([def_action_if_not_found]) $4])]) - -m4_popdef([with_arg]) -m4_popdef([description]) -m4_popdef([def_arg]) - -])dnl PKG_WITH_MODULES - -dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, -dnl [DESCRIPTION], [DEFAULT]) -dnl ----------------------------------------------- -dnl -dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES -dnl check._[VARIABLE-PREFIX] is exported as make variable. -AC_DEFUN([PKG_HAVE_WITH_MODULES], -[ -PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) - -AM_CONDITIONAL([HAVE_][$1], - [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) -])dnl PKG_HAVE_WITH_MODULES - -dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, -dnl [DESCRIPTION], [DEFAULT]) -dnl ------------------------------------------------------ -dnl -dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after -dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make -dnl and preprocessor variable. -AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], -[ -PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) - -AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], - [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) -])dnl PKG_HAVE_DEFINE_WITH_MODULES - m4_include([m4/ax_c_float_words_bigendian.m4]) m4_include([m4/ax_check_openssl.m4]) diff --git a/configure b/configure index b606fc808c17c1..0914e247043832 100755 --- a/configure +++ b/configure @@ -681,11 +681,8 @@ LLVM_PROF_MERGER PGO_PROF_USE_FLAG PGO_PROF_GEN_FLAG LLVM_AR_FOUND -target_os -target_vendor -target_cpu -target LLVM_AR +PROFILE_TASK DEF_MAKE_RULE DEF_MAKE_ALL_RULE ABIFLAGS @@ -856,6 +853,7 @@ LDFLAGS LIBS CPPFLAGS CPP +PROFILE_TASK PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR' @@ -1459,7 +1457,6 @@ _ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] - --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi @@ -1559,6 +1556,8 @@ Some influential environment variables: CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor + PROFILE_TASK + Python args for PGO generation task PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path @@ -6426,6 +6425,16 @@ else DEF_MAKE_RULE="all" fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking PROFILE_TASK" >&5 +$as_echo_n "checking PROFILE_TASK... " >&6; } +if test -z "$PROFILE_TASK" +then + PROFILE_TASK='-m test --pgo' +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 # normal names in the default $PATH (ie: Ubuntu). They exist under the # non-suffixed name in their versioned llvm directory. @@ -6472,47 +6481,9 @@ if test "$Py_LTO" = 'true' ; then case $CC in *clang*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 -$as_echo_n "checking target system type... " >&6; } -if ${ac_cv_target+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$target_alias" = x; then - ac_cv_target=$ac_cv_host -else - ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 -$as_echo "$ac_cv_target" >&6; } -case $ac_cv_target in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; -esac -target=$ac_cv_target -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_target -shift -target_cpu=$1 -target_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -target_os=$* -IFS=$ac_save_IFS -case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac - - -# The aliases save the names the user supplied, while $host etc. -# will get canonicalized. -test -n "$target_alias" && - test "$program_prefix$program_suffix$program_transform_name" = \ - NONENONEs,x,x, && - program_prefix=${target_alias}- -# Extract the first word of "$target_alias-llvm-ar", so it can be a program name with args. -set dummy $target_alias-llvm-ar; ac_word=$2 + 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. +set dummy ${ac_tool_prefix}llvm-ar; 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_AR+:} false; then : @@ -6551,10 +6522,10 @@ $as_echo "no" >&6; } fi +fi if test -z "$ac_cv_path_LLVM_AR"; then - if test "$build" = "$target"; then - ac_pt_LLVM_AR=$LLVM_AR - # Extract the first word of "llvm-ar", so it can be a program name with args. + ac_pt_LLVM_AR=$LLVM_AR + # Extract the first word of "llvm-ar", so it can be a program name with args. set dummy llvm-ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } @@ -6581,7 +6552,6 @@ done done IFS=$as_save_IFS - test -z "$ac_cv_path_ac_pt_LLVM_AR" && ac_cv_path_ac_pt_LLVM_AR="''" ;; esac fi @@ -6594,9 +6564,16 @@ else $as_echo "no" >&6; } fi - LLVM_AR=$ac_pt_LLVM_AR - else + if test "x$ac_pt_LLVM_AR" = x; then LLVM_AR="''" + 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_AR=$ac_pt_LLVM_AR fi else LLVM_AR="$ac_cv_path_LLVM_AR" @@ -6668,8 +6645,9 @@ fi -# Extract the first word of "$target_alias-llvm-profdata", so it can be a program name with args. -set dummy $target_alias-llvm-profdata; ac_word=$2 +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}llvm-profdata", so it can be a program name with args. +set dummy ${ac_tool_prefix}llvm-profdata; 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_PROFDATA+:} false; then : @@ -6708,10 +6686,10 @@ $as_echo "no" >&6; } fi +fi if test -z "$ac_cv_path_LLVM_PROFDATA"; then - if test "$build" = "$target"; then - ac_pt_LLVM_PROFDATA=$LLVM_PROFDATA - # Extract the first word of "llvm-profdata", so it can be a program name with args. + ac_pt_LLVM_PROFDATA=$LLVM_PROFDATA + # Extract the first word of "llvm-profdata", so it can be a program name with args. set dummy llvm-profdata; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } @@ -6738,7 +6716,6 @@ done done IFS=$as_save_IFS - test -z "$ac_cv_path_ac_pt_LLVM_PROFDATA" && ac_cv_path_ac_pt_LLVM_PROFDATA="''" ;; esac fi @@ -6751,9 +6728,16 @@ else $as_echo "no" >&6; } fi - LLVM_PROFDATA=$ac_pt_LLVM_PROFDATA - else + if test "x$ac_pt_LLVM_PROFDATA" = x; then LLVM_PROFDATA="''" + 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_PROFDATA=$ac_pt_LLVM_PROFDATA fi else LLVM_PROFDATA="$ac_cv_path_LLVM_PROFDATA" @@ -9524,6 +9508,14 @@ then # -u libsys_s pulls in all symbols in libsys Darwin/*) LINKFORSHARED="$extra_undefs -framework CoreFoundation" + + # Issue #18075: the default maximum stack size (8MBytes) is too + # small for the default recursion limit. Increase the stack size + # to ensure that tests don't crash + # Note: This matches the value of THREAD_STACK_SIZE in + # thread_pthread.h + LINKFORSHARED="-Wl,-stack_size,1000000 $LINKFORSHARED" + if test "$enable_framework" then LINKFORSHARED="$LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' @@ -10496,6 +10488,9 @@ then $as_echo "#define _REENTRANT 1" >>confdefs.h posix_threads=yes + if test "$ac_sys_system" = "SunOS"; then + CFLAGS="$CFLAGS -D_REENTRANT" + fi elif test "$ac_cv_kpthread" = "yes" then CC="$CC -Kpthread" @@ -11466,13 +11461,13 @@ fi for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ clock confstr copy_file_range ctermid dup3 execv explicit_bzero explicit_memset \ faccessat fchmod fchmodat fchown fchownat \ - fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ + fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ futimens futimes gai_strerror getentropy \ 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 lchmod lchown lockf linkat lstat lutimes mmap \ + 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 \ @@ -16758,9 +16753,12 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #include - atomic_int value = ATOMIC_VAR_INIT(1); + atomic_int int_var; + atomic_uintptr_t uintptr_var; int main() { - int loaded_value = atomic_load(&value); + 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); return 0; } diff --git a/configure.ac b/configure.ac index 3d589ac2589167..7051dc109a725d 100644 --- a/configure.ac +++ b/configure.ac @@ -1293,6 +1293,14 @@ else DEF_MAKE_RULE="all" fi +AC_ARG_VAR(PROFILE_TASK, Python args for PGO generation task) +AC_MSG_CHECKING(PROFILE_TASK) +if test -z "$PROFILE_TASK" +then + PROFILE_TASK='-m test --pgo' +fi +AC_MSG_RESULT($PROFILE_TASK) + # Make llvm-relatec 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. @@ -1330,7 +1338,7 @@ if test "$Py_LTO" = 'true' ; then case $CC in *clang*) AC_SUBST(LLVM_AR) - AC_PATH_TARGET_TOOL(LLVM_AR, llvm-ar, '', ${llvm_path}) + AC_PATH_TOOL(LLVM_AR, llvm-ar, '', ${llvm_path}) AC_SUBST(LLVM_AR_FOUND) if test -n "${LLVM_AR}" -a -x "${LLVM_AR}" then @@ -1396,7 +1404,7 @@ AC_SUBST(LLVM_PROF_MERGER) AC_SUBST(LLVM_PROF_FILE) AC_SUBST(LLVM_PROF_ERR) AC_SUBST(LLVM_PROFDATA) -AC_PATH_TARGET_TOOL(LLVM_PROFDATA, llvm-profdata, '', ${llvm_path}) +AC_PATH_TOOL(LLVM_PROFDATA, llvm-profdata, '', ${llvm_path}) AC_SUBST(LLVM_PROF_FOUND) if test -n "${LLVM_PROFDATA}" -a -x "${LLVM_PROFDATA}" then @@ -2305,7 +2313,7 @@ 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 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 available and at least as big as an off_t. You may need + 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) @@ -2682,6 +2690,14 @@ then # -u libsys_s pulls in all symbols in libsys Darwin/*) LINKFORSHARED="$extra_undefs -framework CoreFoundation" + + # Issue #18075: the default maximum stack size (8MBytes) is too + # small for the default recursion limit. Increase the stack size + # to ensure that tests don't crash + # Note: This matches the value of THREAD_STACK_SIZE in + # thread_pthread.h + LINKFORSHARED="-Wl,-stack_size,1000000 $LINKFORSHARED" + if test "$enable_framework" then LINKFORSHARED="$LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' @@ -3047,6 +3063,9 @@ then # Defining _REENTRANT on system with POSIX threads should not hurt. AC_DEFINE(_REENTRANT) posix_threads=yes + if test "$ac_sys_system" = "SunOS"; then + CFLAGS="$CFLAGS -D_REENTRANT" + fi elif test "$ac_cv_kpthread" = "yes" then CC="$CC -Kpthread" @@ -3522,13 +3541,13 @@ fi AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ clock confstr copy_file_range ctermid dup3 execv explicit_bzero explicit_memset \ faccessat fchmod fchmodat fchown fchownat \ - fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ + fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ futimens futimes gai_strerror getentropy \ 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 lchmod lchown lockf linkat lstat lutimes mmap \ + 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 \ @@ -5384,9 +5403,12 @@ AC_LINK_IFELSE( [ AC_LANG_SOURCE([[ #include - atomic_int value = ATOMIC_VAR_INIT(1); + atomic_int int_var; + atomic_uintptr_t uintptr_var; int main() { - int loaded_value = atomic_load(&value); + 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); return 0; } ]]) @@ -5396,7 +5418,7 @@ AC_MSG_RESULT($have_stdatomic_h) if test "$have_stdatomic_h" = yes; then AC_DEFINE(HAVE_STD_ATOMIC, 1, - [Has stdatomic.h with atomic_int]) + [Has stdatomic.h with atomic_int and atomic_uintptr_t]) fi # Check for GCC >= 4.7 __atomic builtins diff --git a/pyconfig.h.in b/pyconfig.h.in index 20cc901e473bee..aaa7b72cac8840 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -341,6 +341,9 @@ /* Define to 1 if you have the `fdopendir' function. */ #undef HAVE_FDOPENDIR +/* Define to 1 if you have the `fdwalk' function. */ +#undef HAVE_FDWALK + /* Define to 1 if you have the `fexecve' function. */ #undef HAVE_FEXECVE @@ -569,9 +572,9 @@ #undef HAVE_LANGINFO_H /* Defined to enable large file support when an off_t is bigger than a long - and long long is available and 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.) */ + 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.) */ #undef HAVE_LARGEFILE_SUPPORT /* Define to 1 if you have the 'lchflags' function. */ @@ -1022,7 +1025,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H -/* Has stdatomic.h with atomic_int */ +/* Has stdatomic.h with atomic_int and atomic_uintptr_t */ #undef HAVE_STD_ATOMIC /* Define to 1 if you have the `strdup' function. */ diff --git a/setup.py b/setup.py index 598f5819f8f34e..20d7f35652fe50 100644 --- a/setup.py +++ b/setup.py @@ -43,6 +43,7 @@ def 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) @@ -784,6 +785,8 @@ def detect_simple_extensions(self): self.add(Extension("_abc", ["_abc.c"])) # _queue module self.add(Extension("_queue", ["_queuemodule.c"])) + # _statistics module + self.add(Extension("_statistics", ["_statisticsmodule.c"])) # Modules with some UNIX dependencies -- on by default: # (If you have a really backward UNIX, select and socket may not be @@ -805,7 +808,9 @@ def detect_simple_extensions(self): if (self.config_h_vars.get('HAVE_GETSPNAM', False) or self.config_h_vars.get('HAVE_GETSPENT', False)): self.add(Extension('spwd', ['spwdmodule.c'])) - else: + # AIX has shadow passwords, but access is not via getspent(), etc. + # module support is not expected so it not 'missing' + elif not AIX: self.missing.append('spwd') # select(2); not on ancient System V @@ -909,6 +914,10 @@ def detect_readline_curses(self): 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'): @@ -1004,13 +1013,15 @@ def detect_readline_curses(self): self.missing.append('_curses') # If the curses module is enabled, check for the panel module - if (curses_enabled and - self.compiler.find_library_file(self.lib_dirs, panel_library)): + # _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])) - else: + elif not skip_curses_panel: self.missing.append('_curses_panel') def detect_crypt(self): @@ -1348,7 +1359,7 @@ def detect_sqlite(self): ] if CROSS_COMPILING: sqlite_inc_paths = [] - MIN_SQLITE_VERSION_NUMBER = (3, 3, 9) + MIN_SQLITE_VERSION_NUMBER = (3, 7, 2) MIN_SQLITE_VERSION = ".".join([str(x) for x in MIN_SQLITE_VERSION_NUMBER]) @@ -1463,7 +1474,7 @@ def detect_platform_specific_exts(self): # Platform-specific libraries if HOST_PLATFORM.startswith(('linux', 'freebsd', 'gnukfreebsd')): self.add(Extension('ossaudiodev', ['ossaudiodev.c'])) - else: + elif not AIX: self.missing.append('ossaudiodev') if MACOS: @@ -1599,9 +1610,9 @@ def detect_expat_elementtree(self): cc = sysconfig.get_config_var('CC').split()[0] ret = os.system( - '"%s" -Werror -Wimplicit-fallthrough -E -xc /dev/null >/dev/null 2>&1' % cc) + '"%s" -Werror -Wno-unreachable-code -E -xc /dev/null >/dev/null 2>&1' % cc) if ret >> 8 == 0: - extra_compile_args.append('-Wno-implicit-fallthrough') + extra_compile_args.append('-Wno-unreachable-code') self.add(Extension('pyexpat', define_macros=define_macros,